标签:
1 UIView* view = [[[UIView alloc] init] autorelease]; 2 //... 3 //do something with view...clearly forgetting that it has been autoreleased. 4 // 5 [view release];
在iphone开发的时候EXC_BAD_ACCESS这个bug时不容易找到原因的。
首先说一下EXC_BAD_ACCESS 这个错误,可以这么说,90%的错误来源在于对一个已经释放的对象进行release操作,或者操作一个在循环代码中被修改的序列中的对象。虽然使用NSZombieEnabled变量可以帮助你找到问题所在,但有的时候,即使通过设置NSZombieEnabled变量,还是不能定位到问题所在,这个时候,你可以试试重写object的respondsToSelector方法,显示出现EXEC_BAD_ACCESS前访问的最后一个object,下面是具体的步骤:
a、在每个类并且在 other c flags中加入-D _FOR_DEBUG_(记住请只在Debug Configuration下加入此标记)。这样当你程序崩溃时,Xcode的console上就会准确地记录了最后运行的object的方法。的实现文件(.m,.mm)文件中,添加如下代码:
-(BOOL) respondsToSelector : (SEL)aSelector { printf("SELECTOR: %s\n", [NSStringFromSelector(aSelector) UTF8String]); return [super respondsToSelector:aSelector]; }
b、并且在 other c flags中加入-D _FOR_DEBUG_(记住请只在Debug Configuration下加入此标记)。这样当你程序崩溃时,Xcode的console上就会准确地记录了最后运行的object的方法。
在Edit–>Scheme里面 找到Arguments ,在Environment Variables这里添加
把下面2个值设置成YES
NSAutoreleaseFreedObjectCheckEnabled
NSDebugEnabled
这种方法非常好用,建议在建立一个工程的时候,加入此设置
你也可以这样做,在系统抛出异常处设置断点:和上面的含义一样
程序不知道跑到哪个地方就 crash 了,而 crash 又很难重现。
保守的做法是: 在系统抛出异常之前设置断点. (具体来说是在 objc_exception_throw 处设置断点。)
设置步骤为:
1. 在 XCode 按 CMD + 6,进入断点管理窗口;
2. 然后点击右下方的 +,增加新的 Symbolic Breakpoint。
3. 在 Symbol 一栏输入:objc_exception_throw,然后点击 done,完成。
高级装逼技术-GDB
XCode 内置GDB,我们可以在命令行中使用 GDB 命令来调试我们的程序。下面将介绍一些常用的命令以及调试技巧。
po 命令:为 print object 的缩写,显示对象的文本描述(显示从对象的 description 消息获得的字符串信息)。
比如:
上图中,我使用 po 命令显示一个 NSDictionary 的内容。注意在左侧我们可以看到 dict 的一些信息:3 key/value
pairs,显示该 dict 包含的数据量,而展开的信息显示 isa 层次体系(即class 和
metaclass结构关系)。我们可以右击左侧的 dict,选中“Print Description of "dict"”,则可以在控制台输出
dict 的详细信息:
Printing description of dict: {type = immutable dict, count = 3, entries => 0 : {contents = "first"} = {contents = "one"} 1 : {contents = "second"} = {contents = "two"} 2 : {contents = "third"} = {contents = "three"} }
print 命令:有点类似于格式化输出,可以输出对象的不同信息:
如:
(gdb) print (char *)[[dict description] cStringUsingEncoding:4]
(gdb) print (int)[dict retainCount]
(gdb)
注:4是 NSUTF8StringEncoding 的值。
info 命令:我们可以查看内存地址所在信息
比如 "info symbol 内存地址" 可以获取内存地址所在的 symbol 相关信息:
(gdb) info symbol 0x00000001000017f7
比如 "info line *内存地址" 可以获取内存地址所在的代码行相关信息:
(gdb) info line *0x00000001000017f7
show 命令:显示 GDB 相关的信息。如:show version 显示GDB版本信息
(gdb) show version
help 命令:如果忘记某条命令的语法了,可以使用 help 命令名 来获取帮助信息。如:help info 显示 info 命令的用法。
(gdb) help info
常见GDB命令
标签:
原文地址:http://www.cnblogs.com/iCocos/p/4803937.html