`

设置 NSZombieEnabled 定位 EXC_BAD_ACCESS 错误[转]

 
阅读更多

 

 

http://unmi.cc/nszombieenabled-locate-exc_bad_access-error

我们做 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 子类中这样的代码:

01
02
03
04
05
06
07
08
09
10
11
12
static NSMutableArray *array;
 
- (void)viewDidLoad
{
    [super viewDidLoad];
    array = [[NSMutableArray alloc] initWithCapacity:5];
    [array release];
}
 
- (void) viewWillAppear:(BOOL)animated {   
    [array addObject:@"Hello"];
}

上面的代码就会出现 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+< 进到这个窗口。

NSZombieEnabled

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

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

01
02
03
04
05
06
07
08
09
10
static NSMutableArray *array;
 
- (void)viewDidLoad
{
    [super viewDidLoad];
    array = [[NSMutableArray alloc] initWithCapacity:5];
    [array release];
    [array addObject:@"Hello"];
    NSLog(@"%@", [array objectAtIndex:0]);
}

但是一旦加上了 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


分享到:
评论
1 楼 w11h22j33 2012-05-16  
1.点击 Xcode4 菜单 Product -> Edit Scheme -> Arguments, 然后将点击”加号”, 将 NSZombieEnabled 参数加到 Environment Variables 窗口中, 后面的数值写上 ”YES”.

2.在 Xcode4 菜单 Product -> Edit Scheme -> Diagnostics(快捷键:cmd+shift+<) 设置窗口中勾上 Enable Zombie Objects 项。

相关推荐

    查找 EXC_BAD_ACCESS 问题根源的方法

    定位 EXC_BAD_ACCESS 错误的关键在于理解和跟踪对象的生命期。下面是一些常用的技术和工具,可以帮助开发者更快地定位和解决问题: 1. **启用 NSZombieEnabled 变量**:在 Xcode 的项目设置中,为可执行文件添加...

    ios EXC_BAD_ACCESS错误调试

    在iOS开发中,EXC_BAD_ACCESS错误是一种常见的运行时错误,通常是因为程序尝试访问已被释放的内存地址导致的。当程序尝试访问一个已经释放的对象时,系统就会抛出EXC_BAD_ACCESS错误,这在C语言中通常被理解为使用了...

    iOS内存错误EXC_BAD_ACCESS的解决方法

    在iOS开发中,遇到“EXC_BAD_ACCESS”错误是一个常见的挑战,这种错误通常与内存管理问题有关,尤其是对象的过度释放或访问已被释放的内存。本文将深入探讨如何解决这类问题。 首先,理解“EXC_BAD_ACCESS”错误的...

    如何在xcode里面使用内存泄露查找工具

    6. 当发生内存错误时,比如EXC_BAD_ACCESS,可通过设置环境变量NSZombieEnabled来找出尝试向已经释放的对象发送消息的错误。在Xcode中,可以在运行应用的Schema设置中,将NSZombieEnabled环境变量设置为YES。这允许...

    使用Xcode和Instruments调试解决iOS内存泄露

    这里讲述在没有ARC的情况下,如何使用Instruments来查找程序中的内存泄露,以及NSZombieEnabled设置的使用。本文假设你已经比较熟悉Obj-C的内存管理机制。实验的开发环境:XCode4.5.2先下载一个实现准备好的内存泄露...

    iOS内存暴增问题追查与使用陷阱

    在XCode中,我们可以添加NSZombieEnabled标记位来让系统把错误地址打印出来。这可以帮助我们快速定位到崩溃的原因。例如,在上面的代码中,崩溃的原因是`message sent to deallocated instance 0x7179910`。 三、...

    解决iOS7 UIBarButtonItem右移错位问题.

    - 示例代码中提到了一个调试技巧,即通过设置环境变量`NSZombieEnabled`为`YES`,可以在程序崩溃时提供更多关于内存错误的信息,这对于定位和解决复杂的内存管理问题非常有帮助。 - **NSLog格式化输出**: - 示例...

    NSZombie:苹果公司对NSZombie的实现

    当尝试向僵尸对象发送消息时,它不会默默失败,而是会抛出一个异常,提供关于哪个对象引发错误的信息,从而帮助开发者定位问题。 启用NSZombie的方法是在Xcode的项目设置中调整诊断选项。在“Product”菜单中选择...

    Secrets Of An iPhone Developer .pps

    NSZombieEnabled Xcode 3.2 Errors / Warnings Xcode 3.2 Static Analyzer Demo ---App Development--- Provisioning Profile tips iTunes Connect App Submission Tips Analytics tracking Score / Networking ...

    60个免费工具下载

    6. **调试工具**:用于调试程序,快速定位问题。 - **推荐工具**:LogCat、NSZombieEnabled 7. **设计和原型工具**:用于创建应用界面的设计图和交互原型。 - **推荐工具**:Sketch、Adobe XD 8. **模拟器...

Global site tag (gtag.js) - Google Analytics