设置 NSZombieEnabled 定位 EXC_BAD_ACCESS 错误
我们做 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 子类中这样的代码:
<span style="font-size:14px;">staticNSMutableArray *array; - (void)viewDidLoad
{
[superviewDidLoad];
array = [[NSMutableArrayalloc] initWithCapacity:5];
[array release];
} - (void) viewWillAppear:(BOOL)animated {
[array addObject:@"Hello"];
}</span>
上面的代码就会出现 EXC_BAD_ACCESS 错误,但我执行时 Xcode 一出错却是定位在我在 AppDelegate 的 application:didFinishLaunchingWithOptions: 方法上的某行了,如果代码量多了,要查找具体问题非常难,但凭经验了。
不过 NSZombieEnabled 环境变量可以帮我们的忙,就是当设置NSZombieEnabled环境变量后,一个对象销毁时会被转化为_NSZombie,设置NSZombieEnabled后,当你向一个已经释放的对象发送消息,这个对象就不会向之前那样Crash或者产生 一个难以理解的行为,而是放出一个错误消息,然后以一种可预测的可以产生debug断点的方式消失, 因此我们就可以找到具体或者大概是哪 个对象被错误的释放了。
对 Xcode 设置了 NSZombieEnabled 之后,Xcode 会明确定位在行 [array addObject:@"Hello"],然后控制台下报的错误信息是:
*** -[__NSArrayM 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 the environment:点+号添加一项,Name里填NSZombieEnabled,Value填Yes,要保证前面的钩是选中的。
Xcode4 下设置 NSZombieEnabled 的方法:
你可以点击 Xcode4 菜单 Product -> Edit Scheme -> Arguments, 然后将点击”加号”, 将 NSZombieEnabled 参数加到 Environment Variables 窗口中, 后面的数值写上 ”YES”.
或者在 Xcode4 菜单 Product -> Edit Scheme -> Diagnostics 设置窗口中直接勾上 Enable Zombie Objects 即可,Xcode 可用 cmd+shift+< 进到这个窗口。

Xcode4 已经考虑到了现在的要求,所以提供了更便捷的设置的方式,你也可以在这个窗口中设置其他一些参数,你肯定能由此获得更多的帮助信息。
另外再说一下,如果没有为 Xcode 设置 NSZombieEnable,像下面的代码或许可以正确执行,打印出你所期望的结果 “Hello”
<span style="font-size:14px;">staticNSMutableArray *array; - (void)viewDidLoad
{
[superviewDidLoad];
array = [[NSMutableArrayalloc] initWithCapacity:5];
[array release];
} - (void) viewWillAppear:(BOOL)animated {
[array addObject:@"Hello"];
}</span>
但是一旦加上了 NSZombieEnable 设置,上面的代码行 [array addObject:@"Hello"] 也将无法投机取巧了,同样会得到错误提示:
*** -[__NSArrayM addObject:]: message sent to deallocated instance 0x6557370
即使该 array 所指向的内存还是原来的数据也不能逃脱掉 NSZombieEnable 的法眼。也就是之所以未设置 NSZombieEnable 时上面代码能得到正确结果,是因为,虽然 [array release] 是标记为释放掉该内存块,但是后面使用 array 时,因为该指针指向的内存数据未被覆盖,所以未出错,这和 C++ 的指针 delete 后的效果是一样的。
参考:1. 设置NSZombieEnabled解决EXC_BAD_ACCESS错误
2. 查找
EXC_BAD_ACCESS 问题根源的方法
3. XCode调试技巧-纠结的EXC_BAD_ACCESS
设置 NSZombieEnabled 定位 EXC_BAD_ACCESS 错误的更多相关文章
- xCode里面设置NSZombieEnabled定位错误
打开product ->scheme->Edit scheme
- 解决EXC_BAD_ACCESS错误的一种方法--NSZombieEnabled
iOS 程序开发时经常用遇到 EXC_BAD_ACCESS 错误导致 Crash,出现这种错误时一般 Xcode 不会给我们太多的信息来定位错误来源,只是在应用 Delegate 上留下像Thread ...
- 怎么调试EXC_BAD_ACCESS错误
当你遇到了一个EXC_BAD_ACCESS错误,我通常会给开发者几个建议: 1.在可执行选项中设置NSZombieEnabled参数,这有时会帮缩小问题的范围: 2.运行apple的内存检测工具,如 ...
- EXC_BAD_ACCESS错误
EXC_BAD_ACCESS错误 一直都是使用ARC开发,咋就莫名其妙的出现这种EXC_BAD_ACCESS错误. 一直都是是怀疑在block中有着特殊处理,导致了使用时出现了这种错误,查找了好久.. ...
- 关于iOS地图定位中点击设置->隐私->定位服务 闪退问题
iOS8之后,如果应用中用到了地图定位,那么点击设置->隐私->定位服务 再点击该应用有时候会出现闪退问题,其原因是iOS8之后定位中添加了 NSLocationWhenInUseDesc ...
- ios 关于[xxx timeIntervalSinceNow]出现EXC_BAD_ACCESS错误的解决办法
[xxx timeIntervalSinceNow]出现EXC_BAD_ACCESS错误的主要原因是之前的[NSDate date]返回一个autoreleased的NSdata,其被释放掉 解决方法 ...
- Xamarin Android设置界面提示类型错误
Xamarin Android设置界面提示类型错误 错误信息:Integer types not allow (at ‘padding’ with value ’10’)Android界面属性的长度和 ...
- 嵌入式 linux下利用backtrace追踪函数调用堆栈以及定位段错误
嵌入式 linux下利用backtrace追踪函数调用堆栈以及定位段错误 2015-05-27 14:19 184人阅读 评论(0) 收藏 举报 分类: 嵌入式(928) 一般察看函数运行时堆栈的 ...
- linux下利用backtrace追踪函数调用堆栈以及定位段错误
一般察看函数运行时堆栈的方法是使用GDB(bt命令)之类的外部调试器,但是,有些时候为了分析程序的BUG,(主要针对长时间运行程序的分析),在程序出错时打印出函数的调用堆栈是非常有用的. 在glibc ...
随机推荐
- PHPCMS v9.5.8-设计缺陷可重置前台任意用户密码
验证.参考漏洞:http://wooyun.jozxing.cc/static/bugs/wooyun-2015-0152291.html 漏洞出现在/phpcms/modules/member/in ...
- 用redis的订阅发布解决了扫码支付实时响应的问题
一.场景描述: PC收银台的浏览器展示了收款二维码,用户扫了支付二维码,支付完成后,浏览器需要实时响应支付结果. 二.问题描述: 扫码支付的支付结果一般通过服务端回调和主动查询来获取,显示二维码之后, ...
- hdu 4352 数位dp + 状态压缩
XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU2108和HDU2036(叉乘)
hdu2108 判断是否为凸边形 判断连续三点的叉乘 若为凸,内角<180:若为凹,内角>180 所以通过正负来判断 #include <iostream> #include ...
- ubuntu 系统应用安装方式
转载 ubuntu系统软件安装 来源:http://www.linuxidc.com/Linux/2011-02/32211.htm 首先说明一下 ubuntu 的软件安装大概有几种方式:1. d ...
- 使用json-Server与postman快速模拟服务环境搭建
在前后端分离的这种工作模式下,分工明确,各司其职.前端负责展示数据,后端提供数据.然而,在这种过程中对于接口的规范 需要提前制定好.例如根据规范提前模拟数据,这个时候就比较麻烦的.JsonServer ...
- # C语言程序设计第一次作业1234
---恢复内容开始--- C语言程序设计第一次作业 1.求圆面积和周长 输入圆的半径,计算圆的周长和面积 (1)流程图 (2)测试数据及运行结果 测试数据r=3 运行结果 2.判断闰年 输入一个四位年 ...
- GC机制
java虚拟机中的垃圾回收机制是,一个类,当该对象没有更多的应用指向它时,就会被垃圾回收器给回收,从而释放资源.该机制不可以程序员手动调用去回收某个对象,系统自动会去调用,当然程序员可以建议垃圾回收器 ...
- Future学习
接着上一篇继续并发包的学习,本篇说明的是Callable和Future,它俩很有意思的,一个产生结果,一个拿到结果. Callable接口类似于Runnable,从名字就可以看出来了,但 ...
- Python小代码_13_生成两个参数的最小公倍数和最大公因数
def demo(m, n): if m > n: m, n = n, m p = m * n while m != 0: r = n % m n = m m = r return (int(p ...