我们每个人都会使用Xcode的断点,但你是否知道用户断点?接下来我会向你展示如何使用用户断点以及用它们来做什么。如果你已经知道什么是用户断点并且知道如何使用,不妨看一下文章末尾的列表,看看我们在PSPDFKit用它们来做什么。也许你会有一些新的发现!
常规断点
创建常规断点后,它们会在Xcode断点导航器(Breakpoint Navigator)的工作区或项目下出现,这取决于你当时用的是哪个。你可以通过点击列表中或它引用代码左侧的断点标识来启用或禁用一个断点。
这些断点信息存储在指定工作区或项目的个人设置里面,即使你在项目里面提交了个人设置,也仅对你可见。工作于同一项目的同事不会在他们的Xcode里面看到你的断点。
共享断点
右键单击一个断点,选择Shared Breakpoint
,这个断点就会变成对项目中每个人都可见。这对某些你希望每次都要中断的代码路径来说非常有用,例如自定义异常处理程序或其它任何在正常条件下不应该被执行的项目指定代码。结合断点选项和自动继续断点,这能大大提高整体的调试体验。
另一个稍微有点用的地方是,你可以这样:在你APP里的常用执行代码路径添加一个共享断点,例如网络请求完成后,让它自动继续并在每次命中的时候播放一个声音。没错,你可以让你的断点播放声音。提交后就等着看你的同伴为找不出这声音来自哪里而发狂吧。😁不幸的是,在远程环境下恶搞你同伴并不总会有效,这也就是为什么我没在PSPDFKit里做这种事。。。but that might be something to entertain for our retreats(这句实在不知道怎么翻译😅)。
用户断点
还有另外一件用断点能做的事。这是个相当强大的特性,不过在Xcode上有点难找就是。你可以右键单击你的断点,选择Move Breakpoint To > User
,让它变成一个用户断点。
这会把断点移出工作区或项目范围,移到用户范围。这意味着该断点会在你机器上的所有项目里出现。虽然对于项目依赖的东西并没有什么卵用,但有部分断点被移到用户范围的列表后会变得更为有用。最明显的就是Objective-C异常和Swift错误断点,几乎每个人都会把它们加到使用相应语言的项目中。使用用户断点,你只需要添加一次,它们便会出现在你所有的项目中。
我在用户空间里的还有另外一个用户断点,就是在程序启动时激活Reveal
。Reveal
是调试视图相关问题的利器,我经常使用。它需要在你的APP里集成一个服务,而这个服务需要被启动。这可以使用调试器来避免在你的APP里添加调试代码。把这个断点移到用户空间后,你不再需要每个应用都添加一下,相反,如果你的项目里面包含Reveal
服务,它会在你的APP启动时自动开始。这个方法在Reveal
的集成指南里同样有提到。
还有其它一些断点对于每个项目也十分有用。记住,你可以禁用它们,只在需要的时候才启用;我有很多是默认关闭的,但如果我需要,它们就在那儿。下面是我们团队在PSPDFKit
中最喜欢使用的断点列表:
Symbol:
UIViewAlertForUnsatisfiableConstraints
在AutoLayout约束出现问题的时候自动停止。相比于Xcode控制台仅打印日志消息,这种方式会让你对问题更加关注。有助于在早期辨别出布局问题。Symbol:
NSKVODeallocateBreak
在KVO
控诉观察者还存在的地方中断。Symbol:
UIApplicationMain
Debugger command: e @import UIKit
导入UIKit
到调试器中,消除很多地方需要转换成结构体的麻烦。你应该写过很多像p (CGRect)[self bounds]
这样的代码吧?用这个方法就不用转换成CGRect
了。Symbol:
-[UIViewController initWithNibName:bundle:]
Debugger command: po $arg1
在View Controller
初始化的时候打印它的类名。在大型项目上工作或者新接触一个项目,你不会知道所有的View Controller
的名字。如果你试图找出想要修改的View Controller
,只需启用这个断点,把APP跳转到有问题的View Controller
,你就会看到在控制台中打印的类名。Symbol:
-[UIApplication sendAction:toTarget:fromSender:forEvent:]
在事件传递的时候停止,例如点击一个按钮。这和上面的例子十分相似。在你不知道触摸按钮调用了哪个方法的时候启用这个断点。
po $arg3
会打印被调用的selector
,po $arg4
则会打印调用的target
。Exception Breakpoint: Objective-C
Debugger command:po $arg1
当Objective-C断点命中的时候中断,并在 Xcode 的控制台打印出异常。Exception Breakpoint: C++
在C++异常命中的时候中断。Swift Error Breakpoint
在遇到Swift错误的时候中断。Symbol:
_XCTFailureHandler
在单元测试产生错误时中断。如果你跑着单元测试并想在遇到错误的时候中断,这个就是你需要的。