当前位置:Gxlcms > 数据库问题 > 解决EXC_BAD_ACCESS错误的一种方法--NSZombieEnabled(转)

解决EXC_BAD_ACCESS错误的一种方法--NSZombieEnabled(转)

时间:2021-07-01 10:21:17 帮助过:2人阅读

  •    
  • -(void)viewDidLoad  
  • {  
  •     [superviewDidLoad];  
  •     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"],然后控制台下报的错误信息是:

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


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

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

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

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

    解决EXC_BAD_ACCESS错误的一种方法--NSZombieEnabled(转)

    标签:

    人气教程排行