原文地址:http://www.jianshu.com/p/c69f34e436e7
这里记录一下自己学习到的一些XCode调试的方法。这些调试方法可以让我们使用XCode编写代码进行调试时用起来更顺心应手。
XCode的调试方法包括运行时设置断点,打印到控制台,手写命令打印等。
1. 运行时设置断点
在XCode中需要观察的变量所在的代码处添加断点,可以让程序运行到这里暂停。这时鼠标悬停在变量名处,XCode会显示出该变量的信息。
断点的类型分为异常断点(Exception Breakpoint)和符号断点(Symbolic Breakpoint)等,在XCode断点浏览器(Breakpoints Navigator)的左下方可以添加这些断点。
符号断点中的符号可以指方法名称或函数名称。符号断点可以中断某个函数的调用。用户还可以添加执行断点的条件。
![](https://i-blog.csdnimg.cn/blog_migrate/6d75716e92344abaa91f871597d64783.webp?x-image-process=image/format,png)
异常断点可以使程序在每次发生异常时,都会被中断。一般用来捕获未知异常。
2. 打印到控制台
控制台位于XCode的底端,用于打印程序运行过程中的输出信息。在代码中调用NSLog函数,可以打印变量值到控制台中显示出来。
NSLog(@"obj:%@", obj);
需要特别注意的是,尽管NSLog可圈可点,但在实际应用中要防备其可能会引起安全问题,因为任何由NSLog输出的内容都会成为应用程序成品代码
的一部分,也就是说会被任何接触到应用的人看到。只要把设备接入信息管理工具,每个人都能查看控制台信息并查询每一条日志记录。这可能会引发一系列严重后
果,例如向控制台输出机密逻辑算法或者用户密码等信息。
我们可以使用宏来解决调用NSLog方法可能导致的安全问题,只在调试版本中调用NSLog。可以采用全局可访问的头文件,把所有日志记录都灌进去,而且不用担心它们会出现在成品代码当中。
#ifdef DEBUG#define DMLog(...) NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__])#else#define DMLog(...) do { } while (0)
现在如果我们使用DMLog(这个名称可以随便起),它将只向调试版本输出结果,任何成品代码都不会受到影响。PRETTY_FUNCTION也帮上了大忙,它会根据日志信息来源为函数命名。
3. 在控制台端手写命令打印
如果我们在应用的特定点进行中断,一般来说是为了检查对象的当前状态。Xcode为我们提供了一套“variables view(变量视图)”,该视图位于Xcode底部,与控制台相邻的左方区域。理论上讲它的作用是显示与当前环境相关的所有值的实时状态,但在实践中有时无法列出值,或者是并未将值更新为中断时的最新状态。幸运的是,我们可以利用一些非常实用的控制台(console)命令自己进行对象检查工作。1
![](https://i-blog.csdnimg.cn/blog_migrate/028b6d97f80e3bff9a2890e0172453de.webp?x-image-process=image/format,png)
po 命令:为 print object 的缩写,显示对象的文本描述。使用p 命令来处理纯量值,即原生类型(boolean、integer、float等)。
print 命令:有点类似于格式化输出,可以输出对象的不同信息。
expr 表达式:打印表达式。
info 命令:我们可以查看内存地址所在信息。
info line *内存地址:可以获取内存地址所在的代码行相关信息。
show 命令:显示 GDB 相关的信息。如:show version 显示GDB版本信息。
bt: 显示当前进程的函数调用栈的情况;”up num”:查看调用的详细信息;down:返回栈列表;l:显示详细代码信息;p:输出数值。
help 命令:如果忘记某条命令的语法了,用来获取帮助信息。
需要注意的是,上述这些都是GDB的调试命令,在LLDB中会有所差异。随着Xcode 5的发布,LLDB调试器已经取代了GDB,成为了Xcode工程中默认的调试器。
这里需要强调的一个技巧是,通过使用expr 表达式可实现在运行时修改变量的值。2
expr username = @"username"expr password = @"badpassword"
通过上面的代码段,变量username和password分别被重新赋值。
4. 设置NSZombieEnabled、MallocStackLogging、NSAutoreleaseFreedObjectCheckEnabled、NSDebugEnabled
第一种设置方法:
1. Product->Edit Scheme...->Run...->EnvironmentVariables.
2. add NSZombieEnabled,set the value with YES
3. add MallocStackLogging, set the value with YES.
4. add NSAutoreleaseFreedObjectCheckEnabled, set the value with YES.
5. add NSDebugEnabled, set the value with YES.
![](https://i-blog.csdnimg.cn/blog_migrate/4a8d59bc24a4d27746c5cf012fb1f803.webp?x-image-process=image/format,png)
使用场景:
主要为了解决EXC_BAD_ACCESS问题,MallocStackLogging用来启用malloc记录(使用方式 malloc_history${App_PID}${Object_instance_addr})。
第二种设置方法:
直接通过Editing Scheme窗口中的Run选项下的Diagnostics选项卡来设置。
![](https://i-blog.csdnimg.cn/blog_migrate/c363e18516c8b37d3c2fcadc0ebb68f7.webp?x-image-process=image/format,png)
需要注意的问题:
NSZombieEnabled只能在调试的时候使用,千万不要忘记在产品发布的时候去掉,因为NSZombieEnabled不会真正去释放dealloc对象的内存。
5. 重写respondsToSelector方法
实现方式
#ifdef _FOR_DEBUG_-(BOOL) respondsToSelector:(SEL)aSelector { printf("SELECTOR: %s\n", [NSStringFromSelector(aSelector) UTF8String]);return[super respondsToSelector:aSelector]; }#endif
使用方法:
需要在每个object的.m或者.mm文件中加入上面代码(应该可以使用类属实现),并且在other c flags中加入-DFOR_DEBUG(记住请只在Debug Configuration下加入此标记)。这样当你程序崩溃时,XCode的console上就会准确地记录了最后运行的object的方法。
http://mobile.51cto.com/iphone-377138.htm“iOS故障排除指南:基本技巧”
http://my.oschina.net/notting/blog/115294“Xcode LLDB Debug教程”
http://www.2cto.com/kf/201210/162934.html“Xcode调试攻略”