Xcode调试技巧

Xcode从默认使用LLDB后,有很多实用的调试技巧,这里简单介绍一下。

输出被调用的方法/函数

1
NSLog(@"%s", __PRETTY_FUNCTION__);

监测任意的异常

  • Add ALL EXCEPTION breakpoint
  • objc_exception_throw(Add Symbolic Exception)

为任意方法添加断点

以UIView的setFrame方法为例:启动App,挂上Debugger,在任意时刻暂停App,在lldb中输入

1
(lldb) breakpoint set -n "-[UIView setFrame:]"

Sound Breakpoint

添加断点,设置action为sound,然后勾选Automatically continue after evaluating。可以简单地用以确认某些方法是否被调用了。

输出所有线程的backtrace

命中断点后,在lldb中输入:

1
(lldb) bt all

输出View结构

任意时刻暂停App,在lldb中输入:

1
(lldb) po [[[[UIApplication sharedApplication] delegate] window] recursiveDescription]

输出NSData

Debugger中,选中NSData->View Memory,会看到一些无法阅读的数据;
在lldb中,输入:

1
(lldb) po yourDataObject

会得到yourDataObject的地址,用该地址替换掉Memory Viewer中的地址,会自动使用合适的encoding。

Instruments Flags

这在调试多线程应用时格外有用,因为很难保证固定的执行顺序。使用这个特性,需要添加DTPerfomanceSession.framework到Xcode project中。

下面的代码片段,将在使用Instruments时,添加一个flag:

1
2
3
#import <DTPerformanceSession/DTSignalFlag.h>
// ...
DTSendSignalFlag("com.invasivecode.mytracepoints.app.point", DT_POINT_SIGNAL, TRUE);

你也可以在Instruments中显示开始和结束标志:

1
2
3
4
5
6
7
8
9
#import <DTPerformanceSession/DTSignalFlag.h>
// ...
// Put this line at the beggining
DTSendSignalFlag("com.invasivecode.mytracepoints.app.start", DT_START_SIGNAL, TRUE);
// ... more code here
// put this at the end
DTSendSignalFlag("com.invasivecode.mytracepoints.app.end", DT_END_SIGNAL, TRUE);

Reference:

附小广告一则:唱吧iOS团队诚招iOS工程师,推荐成功即奖励6000元现金或iPhone 6一部,详见这篇blog