IOS里面查找和解决僵尸对象

内存泄漏是当一个对象或变量在使用完成后没有释放掉,那么如果我们走了另外一个极端情况会什么样呢?这就导致过度释放(over release)问题,从而使对象“僵尸化”,对象称为僵尸(zombies)对象。一个对象已经被释放过了,或者调用者没有这个对象的所有权而释放它, 都会造成过度释放,产生僵尸对象。试图调用僵尸对象方法应用会崩溃(应用直接跳出),并抛出异常EXEC_BAD_ACCESS,那么EXEC_BAD_ACCESS给予的提示通常是毫无debug价值的信息。

 

简单一句话描述:

僵尸对象:已经被回收的对象,或者说对象所对应的内存地址已经不可用的对象称为僵尸对象。僵尸对象不可用

 

下面是一段有问题的代码

 1 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
 2  
 3 { 
 4  
 5     NSUInteger row = [indexPath row]; 
 6  
 7     NSDictionary *rowDict = [self.listTeams objectAtIndex:row]; 
 8  
 9     NSString *rowValue  =  [rowDict objectForKey:@"name"]; 
10  
11     NSString *message = [[NSString alloc] initWithFormat:@”您选择了%@队。”, rowValue]; 
12  
13     UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@”请选择球队” message:message delegate:self cancelButtonTitle:@”Ok” otherButtonTitles:nil]; 
14  
15     [alert release];                                                                                                                                           
16  
17     [message release]; 
18  
19     [alert show];                                                                                                                                              
20  
21     [tableView deselectRowAtIndexPath:indexPath animated:YES]; 
22  
23 }
View Code

程序运行的结果抛出EXEC_BAD_ACCESS异常。

 

 

如何调试:

 

 

NSZombieEnabled变量用来调试与内存有关的问题,跟踪对象的释放过程。启用了NSZombieEnabled的话,它会用一个僵尸来替换默认的dealloc实现,也就是在引用计数降到0时,该僵尸实现会将该对象转换成僵尸对象。僵尸对象的作用是在你向它发送消息时,它会显示一段日志并自动跳入调试器。

          所以,当在应用中启用NSZombie而不是让应用直接崩溃掉时,一个错误的内存访问就会变成一条无法识别的消息发送给僵尸对象。僵尸对象会显示接受到得信息,然后跳入调试器,这样你就可以查看到底是哪里出了问题。

         可以在Xcode的scheme页面中设置NSZombieEnabled环境变量。点击Product——>Edit Scheme打开该页面,然后勾选Enable Zombie Objects 复选框。


blob.png

 

僵尸在ARC出现以前作用不大。但自从有了ARC,如果你在对象的所有权方面比较注意,那么通常不会碰到与内存相关的崩溃。

posted on 2014-10-16 14:15  Keir Lee  阅读(2164)  评论(0编辑  收藏  举报

导航