您的位置:首页 > 其它

使用NSZombie解决EXC_BAD_ACCESS问题

2014-03-13 22:24 405 查看


一.EXC_BAD_ACCESS问题

当向一个已经释放的对象发送消息时,就会使程序崩溃,但调试器仅打印出EXC_BAD_ACCESS错误,而没有其它信息提示是哪个对象导致的。

为了找到那那个提前被释放的对象,可以启动NSZombie。启用NSZombie后,对象被完全释放后就转化为NSZombie,但其内存并没有被释放,仍然可用。这时候向NSZombie(即已被完全释放的对象)发送消息时,因内存仍可用,程序不会crash,而调试器此时也可得知此已释放对象的地址,类型以及发向其的消息是什么。


二.解决方法

有两种方式启用NSZombie,一是设置NSZombieEnabled环境变量,二是使用Instruments的Zombies检测。


2.1 示例代码

iphone-memory-debug-nszombie中的ZombieDebug
Demo Project代码来演示这两种方法,异常位置自己去找。
@implementation ZombieDebugViewController

@synthesize objArray;

-(void)rewriteText {
NSMutableString* s = [NSMutableString stringWithCapacity:100];
for (id obj in objArray) {
[s appendFormat:@"%@,\n",obj];
[obj release];
}
label.text = s;
}

- (void)viewDidLoad {
[super viewDidLoad];
self.objArray = [NSMutableArray arrayWithCapacity:10];
[objArray addObject:@"I'm a string object"];
[self rewriteText];
}

-(IBAction) tapButton:(id)button {
NSNumber* n = [NSNumber numberWithLong:random()];
[objArray addObject:n];
[self rewriteText];
}

-(void)dealloc {
[super dealloc];
self.objArray=nil;
}

@end


2.2.方法1-启用NSZombieEnabled环境变量

在xCode4中的设置方法为 Product->EditScheme->Run->Environment Variables, 添加NSZombieEnabled环境变量并设为YES。如图所示。





当设置NSZombieEnabled为YES后,运行程序,此时程序不再crash,而是在向已释放对象发送消息的位置断住,并在调试器中打印中引起异常对象的消息。如图所示




2012-05-29 22:47:10.911 ZombieDebug[828:f803] *** -[CFNumber respondsToSelector:]: message sent to deallocated instance 0x687c4e0





即向CFNumber对象发送respondsToSelector消息时检测到异常,0x687c4e0地址的CFNumber对象已经被释放。

注:因启动NSZombie后,本应释放的内存变成了NSZombie而不被释放,会使程序占用的内存越来越多,所以只能在调试时设置NSZombieEnabled环境变量,在发布时要去除。

使用NSZombieEnabled环境变量的方法只能知道哪个对象出了问题,而不知道该对象的分配释放流程,所以很难分析在哪一步出了问题,使用Instruments的NSZombie检测可以完整的跟踪对象的retain,release流程,从而分析哪一次释放为异常释放。


2.3 方法2-使用Instruments的NSZombie检测

使用菜单Product->Profile可以启动Instruments,如图所示,选择Zombies模板。





Zombies模板是Allocations模板的一个特例,其启用了Record Reference Counts和Enable NSZombie detection。





当Instruments中点击record运行程序,当有向NSZombie发送消息时,会有消息提醒。如图





点击图中的箭头后,就显示出此对象所有的retain,release,autorelease过程,便于分析哪里进行了不正常的释放。



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: