这是我的情况:我有一个显示联系人的表格视图.导航栏中的"添加"按钮用于加载另一个数据输入视图.这个新视图在表头中有图像,每个表格单元都有一个UITextField或一个UITextView.当我按下取消时,弹出视图并释放内存.
这是我的问题:当我打开"添加"界面时,在任何UITextField或UITextView中提供一个值,然后按"取消"返回到父视图,我收到一个EXC_BAD_ACCESS错误.当我跟踪它时,"添加控制器"正确调用dealloc,但在[super dealloc]之后按下Continue时,它会抛出此错误.就是这样,没有任何痕迹,虽然我正在使用NSZombieEnabled.当我用Instruments运行代码时,我没有得到任何错误:(
我希望我能解释这个问题.有什么指针吗?谢谢.
导致此错误的最常见原因是当您释放对象时,某些其他机制会在以后尝试访问/释放/释放它.
每当我收到EXC_BAD_ACCESS
错误报告时,我的第一个建议是逐步执行代码以确定导致它的行,然后搜索[object release]
引用该对象的任何显式调用.逐一评论它们以找出您可能出错的地方(当然,确保稍后正确释放该对象).
如果该行无法帮助您找出导致问题的对象,请开始查看您的[object release]
调用,并确保您没有意外释放对象太多次,或者释放不是拥有.
这导致了一个关于release
Objective-C 的良好的一般准则:
如果您拥有一个对象(分配或保留它),则将其释放.如果您不拥有它(通过便利方法或其他人分配它),您不会释放它.
(通过使用Objective C/Cocoa/iPhone的内存管理,这也有一些很好的提示.)
虽然这通常是内存管理不善的结果,但它可能由于其他原因而发生(并且比简单地打开更难调试NSZombieEnabled
).例如,如果您未能为格式字符串提供正确数量的参数(即在调试其他问题时NSLog
),即使启用了所有调试参数,也可能最终没有堆栈跟踪.幸运的是,您可以在Xcode中使用GDB 将堆栈跟踪恢复到以前的状态.
在GDB控制台中,您应该看到崩溃程序的指令.找到失败之前的最后一条成功返回指令.它应该看起来像这样:
je 0x986cef35
注意十六进制值并在GDB中执行以下操作:
set $eip = 0x986cef35 stepi where
你应该(希望)现在拥有更丰富的堆栈跟踪.
来源(与上面的链接相同)