我们做iOS 程序开发时经常用遇到 EXC_BAD_ACCESS 错误导致 Crash,出现这种错误时一般 Xcode 不会给我们太多的信息来定位错误来源,只是在应用 Delegate 上留下像Thread 1: Program received signal:"EXC_BAD_ACCESS",让问题无从找起。

比如你对已释放的对象发送消息时就会出现,EXC_BAD_ACCESS,再如release 的对象再 release,release 那些autorelease 的对象等也会报这样的错。默认设置下 Xcode 不会给你定位具体是哪一行代码,不该去使用已释放的对象,或者release 用错了。

比如 UIViewController 子类中这样的代码:

[cpp] view plaincopyprint?
  1. static NSMutableArray*array;
  2. -(void)viewDidLoad
  3. {
  4. [superviewDidLoad];
  5. array= [[NSMutableArray alloc]initWithCapacity:5];
  6. [array release];//释放掉该数组
  7. }
  8. - (void)viewWillAppear:(BOOL)animated{
  9. [array addObject:@"Hello"];//使用释放掉的数组
  10. }

上面的代码就会出现EXC_BAD_ACCESS 错误,但我执行时 Xcode 一出错却是定位在我在 AppDelegate 的 application:didFinishLaunchingWithOptions: 方法上的某行了,如果代码量多了,要查找具体问题非常难,但凭经验了。

不过NSZombieEnabled 环境变量可以帮我们的忙,就是当设置NSZombieEnabled环境变量后,一个对象销毁时会被转化为_NSZombie,设置NSZombieEnabled后,当你向一个已经释放的对象发送消息,这个对象就不会向之前那样Crash或者产生一个难以理解的行为,而是放出一个错误消息,然后以一种可预测的可以产生debug断点的方式消失, 因此我们就可以找到具体或者大概是哪个对象被错误的释放了。

对 Xcode 设置了NSZombieEnabled 之后,Xcode 会明确定位在行[array addObject:@"Hello"],然后控制台下报的错误信息是:

*** -[__NSArray addObject:]:message sent to deallocated instance 0x6557370

如何设置 NSZombieEnabled 呢,在 Xcode3 和 Xcode4 下设置不一样,Xcode4 下设置很简单。
Xcode3 下 NSZombieEnabled 设置方法如下:

1.   在XCode左边那个Groups& Files栏中找到Executables,双击其中的一项,或者右键Get Info;
2.  切换到Arguments 
3.  这里一共有两个框,在下面那个Variables to be set in theenvironment:点+号添加一项,Name里填NSZombieEnabled,Value填Yes,要保证前面的钩是选中的。

Xcode4 下设置 NSZombieEnabled 的方法:

你可以点击 Xcode4 菜单 Product -> Edit Scheme-> Arguments, 然后将点击”加号”, 将 NSZombieEnabled 参数加到Environment Variables 窗口中, 后面的数值写上 ”YES”.

或者在 Xcode4 菜单 Product -> EditScheme -> Diagnostics 设置窗口中直接勾上Enable ZombieObjects 即可,Xcode 可用 cmd+shift+< 进到这个窗口。

Xcode4 已经考虑到了现在的要求,所以提供了更便捷的设置的方式,你也可以在这个窗口中设置其他一些参数,你肯定能由此获得更多的帮助信息。

另外再说一下,如果没有为 Xcode 设置 NSZombieEnable,像下面的代码或许可以正确执行,打印出你所期望的结果“Hello”

[cpp] view plaincopyprint?
  1. static NSMutableArray*array;
  2. -(void)viewDidLoad
  3. {
  4. [super viewDidLoad];
  5. array= [[NSMutableArray alloc]initWithCapacity:5];
  6. [array release];
  7. [array addObject:@"Hello"];//之所以不会crash,是在于事件周期未完,内存回收机制还没有执行,没有真正的回收掉array的对象内存。
  8. NSLog(@"%@",[array objectAtIndex:0]);
  9. }

但是一旦加上了NSZombieEnable 设置,上面的代码行  [array addObject:@"Hello"] 也将无法投机取巧了,同样会得到错误提示:

*** -[__NSArrayM addObject:]:message sent to deallocated instance 0x6557370

即使该array 所指向的内存还是原来的数据也不能逃脱掉 NSZombieEnable 的法眼。也就是之所以未设置 NSZombieEnable 时上面代码能得到正确结果,是因为,虽然 [array release] 是标记为释放掉该内存块,但是后面使用 array 时,因为该指针指向的内存数据未被覆盖,所以未出错,这和C++ 的指针 delete 后的效果是一样的。

最后提醒NSZombieEnabled只能在调试的时候使用,千万不要忘记在产品发布的时候去掉,因为NSZombieEnabled不会真正去释放dealloc对象的内存,一直开启后果可想而知,自重!

注:

1.苹果官方的Mac OS X Debugging Magic,详细讲述了最为一个高级苹果程序员应该具备的调试技巧 http://developer.apple.com/library/mac/#technotes/tn2004/tn2124.html

2.其实还可以在Instruments中开启NSZombie选项,这样就可以在Instruments中直接查看crash时候的callstack了:http://www.markj.net/iphone-memory-debug-nszombie/

本文转载自:http://blog.csdn.net/likendsl/article/details/7566305

NSZombieEnabled使用相关推荐

  1. 如何在Xcode 4中设置NSZombieEnabled?

    如何在Xcode 4中为我的可执行文件设置NSZombieEnabled和CFZombieLevel ? #1楼 在Xcode 4.2中 项目名称/编辑方案/诊断/ 启用Zombie Objects复 ...

  2. 设置 NSZombieEnabled 定位 EXC_BAD_ACCESS 错误

    http://unmi.cc/nszombieenabled-locate-exc_bad_access-error, 来自 隔叶黄莺 Unmi Blog 我们做 iOS 程序开发时经常用遇到 EXC ...

  3. 解决EXC_BAD_ACCESS错误的一种方法--NSZombieEnabled

    版权声明:本文为博主原创文章,未经博主允许不得转载. 我们做iOS 程序开发时经常用遇到 EXC_BAD_ACCESS 错误导致 Crash,出现这种错误时一般 Xcode 不会给我们太多的信息来定位 ...

  4. 如何定位EXC_BAD_ACCESS错误 (info malloc-history)

    在 iphone 开发中使用内存时,我们经常会遇到 EXC_BAD_ACCESS 的错误. 出现这个错误的原因是我们访问了一个已经被释放掉的对象,如: @implementation Feedback ...

  5. iOS实录15:浅谈iOS Crash

    导语:在当前的iOS开发中,虽然ARC为开发者解决了手动内存管理时代 的许多麻烦,但是内存方面的问题依然是产生iOS Crash的元凶之一,本文介绍内存方面,有关僵尸对象.野指针.内存泄漏.废弃内存这 ...

  6. iphone XCode调试技巧之EXC_BAD_ACCESS中BUG解决

    http://mobile.51cto.com/iphone-279455.htm XCode调试技巧之EXC_BAD_ACCESS中BUG解决是本文要介绍的内容,在iphone开发的时候EXC_BA ...

  7. 使用Xcode和Instruments调试解决iOS内存泄露(转)

    转自:http://blog.csdn.net/totogo2010/article/details/8233565 虽然iOS 5.0版本之后加入了ARC机制,由于相互引用关系比较复杂时,内存泄露还 ...

  8. EXC_BAO_ACCESS引起的奔溃信息

    ios开发中,最郁闷的莫过于程序毫无征兆的就奔溃了,用bt命令打出调用栈 给出的使一堆EXC_BAO_ACCESS的信息  根本没有办法定位问题出在哪里 通常这样的奔溃出现  原因一般就是:调用已经释 ...

  9. 程序Crash后的调试技巧

    当我们的程序突然死掉了,Xcode突然送出一段 "message sent to deallocated instance" 的错误,我们该怎样定位我们的程序bug呢? 又或者我们 ...

最新文章

  1. 公司用的 MySQL 团队开发规范
  2. mysql 存储过程 格式化_转 mysql 存储过程初探
  3. Android之安装常见的一些解决方法
  4. 残差学习,152层网络,微软夺冠2015 ImageNet计算机视觉识别挑战
  5. CCP/XCP和T-BOX知识点
  6. 在大项目中,实施顾问主要负责什么具体工作?
  7. 正则表达式的学习使用
  8. Java JDK下载安装及环境配置超详细图文教程
  9. 黑莓7100刷机及修改PIN,完美破解超越输入法
  10. 代码走查-放过疑点就是埋雷
  11. JAVA打印数组的四种方法
  12. 又一家流血上市!AI四小龙之首商汤科技冲刺IPO,三年半巨亏242亿
  13. C++的虚函数表指针vptr
  14. matplotlib plot显示marker超出边界部分
  15. 电脑上的文件乱码了怎么修复?
  16. YOLOv5 anchor 编码(label assign)方式详解
  17. 献给在这个世界上摇摆不定的朋友们
  18. 永恒之蓝漏洞复现测试
  19. 万科为并购平台投资39亿,王石退路浮出水面
  20. 布朗大学计算机研究生申请,布朗大学计算机科学理学硕士研究生申请要求及申请材料要求清单...

热门文章

  1. Spring入门之一-------实现一个简单的IoC
  2. mysql的字码设置方法
  3. ABAP术语-World Wide Web
  4. 动态代理Java实现
  5. jQuery Easy UI Accordion(可伸缩的面板)包
  6. 暑训day1解题报告
  7. dotNet中初始化器的使用
  8. 实例学习SSIS(五)--理论介绍SSIS
  9. Python的bool类型
  10. day07-vue项目-搭建项目到登录功能