开发中常见的一类崩溃错误是遇到:unrecognized selector sent to instance 0xaxxxx…而backtrace又无法明确说明错误在哪行代码,如何快速定位BUG呢?
有时读代码一下很难找到是哪个instance出的问题,这时定制有效的DEBUG断点是最好的办法,方法如下:
在Debug菜单中选择 Breakpoints -> Create Symbolic Breakpoint
在Symbol中填写如下方法签名:
-[NSObject(NSObject) doesNotRecognizeSelector:]
然后再运行复现错误时断点会停在真正导致崩溃的地方。
Symbolic Beakpoint 功能很强大, 具体的设置可以添加时进行设置, 也可以添加后, 在断点浏览面板(Command + 7)进行设置.
Symbol:
触发断点的函数
C函数样式只需要写函数名,不用写后面的()和参数。例如NSLog。
OC方法样式的[className methodName] className是类名,methodName是方法名(不区分类方法和实例方法)。如果写标记的这个类的方法被子类重写了则子类的方法也会触发断点。例如[UIViewController viewDidLoad]。
Module:
模块筛选。可以避免不同库中方法名或者函数名相同。
Condition
触发条件。这里可以添加一些指定触发条件,比如添加第一个参数不能为nil。这里$arg3代表第1个参数,$arg4代表第2个参数,以此类推。这里也可以调用方法来判断,但必须是类方法,并且返回值必须为BOOL类型。
样例:找出给[UIImage imageNamed:]传nil的代码。这里就需要设置Symbol为[UIImage imageNamed:],然后Condition设置为$arg3 == nil。这样在运行中如果遇到传nil就会触发断点。
Action
触发活动。这里是当断点触发后要执行的动作,可以添加多条,执行的顺序是从上到下。一共有6种可执行类型。
- AppleScript
会在断点触发的时候执行Mac OS X内置的一种功能强大的脚本语言,具体写法可以自行百度AppleScript。 - Capture GPU Frame
- Debugger Command
会在断点触发的时候执行LLDB命令。可以打印对象、修改对象值等功能。 - Log Message
会在断点触发的时候打印日志。其中@exp@
打印对象值,exp
为对象名;%B
表示断点名;%H
表示当前断点触发的次数。 - Shell Command
会在断点触发的时候执行Shell命令。
Sound
触发声音。感觉很炫酷,但没点用的功能。适合装逼。 - Options
是否进入DEBUG界面。勾选这个断点触发后不进入DEBUG界面,断点打印日志或者声音断点一般都勾选。