使用NSZombie解决EXC_BAD_ACCESS问题
2014-03-13 22:24
405 查看
一.EXC_BAD_ACCESS问题
当向一个已经释放的对象发送消息时,就会使程序崩溃,但调试器仅打印出EXC_BAD_ACCESS错误,而没有其它信息提示是哪个对象导致的。为了找到那那个提前被释放的对象,可以启动NSZombie。启用NSZombie后,对象被完全释放后就转化为NSZombie,但其内存并没有被释放,仍然可用。这时候向NSZombie(即已被完全释放的对象)发送消息时,因内存仍可用,程序不会crash,而调试器此时也可得知此已释放对象的地址,类型以及发向其的消息是什么。
二.解决方法
有两种方式启用NSZombie,一是设置NSZombieEnabled环境变量,二是使用Instruments的Zombies检测。
2.1 示例代码
以iphone-memory-debug-nszombie中的ZombieDebugDemo Project代码来演示这两种方法,异常位置自己去找。
@implementation ZombieDebugViewController @synthesize objArray; -(void)rewriteText { NSMutableString* s = [NSMutableString stringWithCapacity:100]; for (id obj in objArray) { [s appendFormat:@"%@,\n",obj]; [obj release]; } label.text = s; } - (void)viewDidLoad { [super viewDidLoad]; self.objArray = [NSMutableArray arrayWithCapacity:10]; [objArray addObject:@"I'm a string object"]; [self rewriteText]; } -(IBAction) tapButton:(id)button { NSNumber* n = [NSNumber numberWithLong:random()]; [objArray addObject:n]; [self rewriteText]; } -(void)dealloc { [super dealloc]; self.objArray=nil; } @end
2.2.方法1-启用NSZombieEnabled环境变量
在xCode4中的设置方法为 Product->EditScheme->Run->Environment Variables, 添加NSZombieEnabled环境变量并设为YES。如图所示。当设置NSZombieEnabled为YES后,运行程序,此时程序不再crash,而是在向已释放对象发送消息的位置断住,并在调试器中打印中引起异常对象的消息。如图所示
2012-05-29 22:47:10.911 ZombieDebug[828:f803] *** -[CFNumber respondsToSelector:]: message sent to deallocated instance 0x687c4e0
即向CFNumber对象发送respondsToSelector消息时检测到异常,0x687c4e0地址的CFNumber对象已经被释放。
注:因启动NSZombie后,本应释放的内存变成了NSZombie而不被释放,会使程序占用的内存越来越多,所以只能在调试时设置NSZombieEnabled环境变量,在发布时要去除。
使用NSZombieEnabled环境变量的方法只能知道哪个对象出了问题,而不知道该对象的分配释放流程,所以很难分析在哪一步出了问题,使用Instruments的NSZombie检测可以完整的跟踪对象的retain,release流程,从而分析哪一次释放为异常释放。
2.3 方法2-使用Instruments的NSZombie检测
使用菜单Product->Profile可以启动Instruments,如图所示,选择Zombies模板。Zombies模板是Allocations模板的一个特例,其启用了Record Reference Counts和Enable NSZombie detection。
当Instruments中点击record运行程序,当有向NSZombie发送消息时,会有消息提醒。如图
点击图中的箭头后,就显示出此对象所有的retain,release,autorelease过程,便于分析哪里进行了不正常的释放。
相关文章推荐
- NSZombieEnabled 解决EXC_BAD_ACCESS错误 去掉僵尸代码
- 解决EXC_BAD_ACCESS错误的一种方法--NSZombieEnabled
- cocos2d 3.11.1使用粒子效果引起的EXC_BAD_ACCESS问题
- 解决EXC_BAD_ACCESS错误的一种方法--NSZombieEnabled
- EXC_BAD_ACCESS(code=1问题的解决办法
- 使用Instruments解决EXC_BAD_ACCESS
- 解决EXC_BAD_ACCESS错误的一种方法--NSZombieEnabled
- 初次使用ASIHttpRequest,出现EXC_BAD_ACCESS问题
- 解决EXC_BAD_ACCESS错误的一种方法--NSZombieEnabled
- 由xCode4里面设置NSZombieEnabled,解决EXC_BAD_ACCESS问题引出
- 如何解决奔溃问题--SIGABRT和EXC_BAD_ACCESS
- NSZombieEnabled 解决EXC_BAD_ACCESS错误
- 解决EXC_BAD_ACCESS错误的一种方法--NSZombieEnabled
- ios 调试技巧收藏 一 解决EXC_BAD_ACCESS错误的一种方法--NSZombieEnabled
- 解决EXC_BAD_ACCESS错误的一种方法--NSZombieEnabled
- Xcode 解决EXC_BAD_ACCESS错误的一种方法--NSZombieEnabled
- 使用Instruments解决EXC_BAD_ACCESS
- ios 调试技巧收藏 一 解决EXC_BAD_ACCESS错误的一种方法--NSZombieEnabled
- 解决EXC_BAD_ACCESS错误的一种方法--NSZombieEnabled
- NSZombieEnabled ,解决EXC_BAD_ACCESS错误的一种方法