如何定位EXC_BAD_ACCESS错误 (info malloc-history)

在 iphone 开发中使用内存时,我们经常会遇到 EXC_BAD_ACCESS 的错误。 出现这个错误的原因是我们访问了一个已经被释放掉的对象,如:
@implementation FeedbackViewController
- (void)viewDidLoad {
	[super viewDidLoad];
	_scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 53, 320, 389)];
	[self.view addSubview:_scrollView];
	[_scrollView release];
}
- (void)dealloc {
	[_scrollView release];
	[super dealloc];
}
@end
在上面的代码中,_scrollView 是 FeedbackViewController 中的一个数据成员。_scrollView 创建后先加入到父视图中,然后将其 release,此时 _scrollView 的引用计数应该为1,在父视图销毁时,_scrollView 会被释放掉,这正是我们期望的结果。 但是 FeedbackViewController 的 dealloc 函数中,对 _scrollView 对象又进行了一次 release,很显然这会造成对象的多次释放。 执行上面的代码,在 FeedbackViewController 退出时,[_scrollView release]; 会引起程序异常退出,且在控制台中输出 EXC_BAD_ACCESS : exc_bad_access 根据这个信息很难判断是哪儿出了问题。

问题解决


打开可执行文件的属性: exec-get-info 打开 Executable [YourApp] Info 界面,在 Variables to be set in the enviroment 中加入以下两个环境变量,将其值设置为 YES,并确保被钩选。 MallocStackLogging NSZombieEnabled exec-info 设置完成后,再次执行前面引起 EXC_BAD_ACCESS 异常的步骤,这时控制台会输出如下信息:
2012-03-15 22:02:12.029 AlipayPortal[616:207] *** -[CALayer retainCount]: message sent to deallocated instance 0x14e48a40
这个输出中有个很重要的信息就是定位到了无效对象在内存中的地址,我们已经打开了 MallocStackLoggin 选项,编译器会记录该内存的分配堆栈。在控制台中输入以下命令:
(gdb) info malloc-history 0x14e48a40
会得到以下输出: console-callstack 根据第10行就可以定位到创建对象的代码,这样也就容易查找 EXC_BAD_ACCESS 的问题了。

posted on 2012-11-13 09:56  流れ星ーー  阅读(1019)  评论(0编辑  收藏  举报

导航