收到EXC_BAD_ACCESS信号
将应用程序部署到设备时,程序将在几个周期后退出,并出现以下错误:
Program received signal: "EXC_BAD_ACCESS".
该程序在iPhone模拟器上运行时没有任何问题,只要按照说明逐步执行,它也将进行debugging和运行。 一旦我让它再次运行,我会击中EXC_BAD_ACCESS
信号。
在这种特殊情况下,它恰好是加速度计代码中的一个错误。 它不会在模拟器中执行,这就是为什么它不会抛出任何错误。 但是,一旦部署到设备,它就会执行。
这个问题的大部分答案都是针对一般的EXC_BAD_ACCESS
错误,所以我将把这个问题留给可怕的Bad Access错误。
EXC_BAD_ACCESS
通常是由非法内存访问引起的。 您可以在下面的答案中find更多信息。
您之前是否遇到过EXC_BAD_ACCESS
信号,您是如何处理的?
从你的描述我怀疑最有可能的解释是,你的内存pipe理有一些错误。 你说你一直在研究iPhone开发几个星期,而不是你是否对Objective C有一般的经验。 如果你是来自另一个背景,那么在你真正内化内存pipe理规则之前可能需要一点时间,除非你把重点放在这里。
请记住,从分配函数(通常是静态分配方法,但还有其他一些方法)或复制方法中获得的任何东西,您也拥有内存,并且在完成后必须释放它。
但是,如果你从包括工厂方法在内的任何其他东西(例如[NSString stringWithFormat]
)中得到一些东西,那么你将有一个autorelease引用,这意味着它可以在未来某个时候被其他代码释放 – 所以它是至关重要的如果你需要把它保留在你保留的直接函数之外。 如果你不这样做,在你使用它的时候内存可能会保持分配状态,或者在你的模拟器testing期间被释放,但仍然是有效的,但是更可能被释放,并且在设备上运行时出现错误的访问错误。
跟踪这些事情的最好方法是,一个好主意(即使没有明显的问题)是在Instruments工具中运行应用程序,尤其是使用Leaks选项。
EXC_BAD_ACCESS的主要原因是尝试访问已发布的对象。
要了解如何排除故障,请阅读以下文档: DebuggingAutoReleasePool
即使你不认为你是“释放自动释放的对象”,这将适用于你。
这个方法工作得非常好。 我一直使用它,并取得了巨大的成功!
总之,这解释了如何使用Cocoa的NSZombiedebugging类和命令行“malloc_history”工具来准确地find在你的代码中被访问的对象。
边注:
运行仪器并检查泄漏将无助于EXC_BAD_ACCESS的故障排除。 我很确定内存泄漏与EXC_BAD_ACCESS无关。 泄漏的定义是你无法访问的对象,因此你不能调用它。
更新:我现在使用仪器来debugging泄漏。 从Xcode 4.2,selectProduct-> Profile,当Instruments启动时,select“Zombies”。
EXC_BAD_ACCESS信号是将无效指针传递给系统调用的结果。 我今天早些时候拿到了一个关于OS X的testing程序 – 我将一个未初始化的variables传递给pthread_join()
,这是由于之前的错字。
我不熟悉iPhone的开发,但你应该仔细检查你传递给系统调用的所有缓冲区指针。 一路-Wextra
编译器的警告级别(使用gcc,使用-Wall
和-Wextra
选项)。 在仿真器/debugging器上尽可能多地启用诊断。
根据我的经验,这通常是由非法的内存访问造成的。 检查所有指针,特别是对象指针,以确保它们已被初始化。 确保你的MainWindow.xib文件,如果你正在使用,正确设置了所有必要的连接。
如果没有任何纸上检查能够解决任何问题,并且在单步执行时不会发生,请尝试使用NSLog()语句来查找错误:将代码与它们一起撒上,然后移动它们,直到find引起该错误的行错误。 然后在该行设置一个断点并运行你的程序。 当你点击断点时,检查所有的variables及其中的对象,看看是否有任何东西看起来像你期望的。我特别留意variables的对象类是你没有想到的东西。 如果一个variables应该包含一个UIWindow,但是它有一个NSNotification,那么当debugging器不运行时,相同的底层代码错误可能会以不同的方式显示出来。
我只花了几个小时追踪EXC_BAD_ACCESS,发现NSZombies和其他env vars似乎没有告诉我什么。
对我来说,这是一个愚蠢的NSLog声明与格式说明符,但没有parameter passing。
NSLog(@"Some silly log message %@-%@");
由…修复
NSLog(@"Some silly log message %@-%@", someObj1, someObj2);
苹果开发者计划的任何参与者都可以看到2010年的WWDCvideo。 有一个伟大的video:“会议311 – 仪器高级内存分析”,显示了一些在仪器中使用僵尸和debugging其他内存问题的例子。
有关login页面的链接,请点击这里 。
不是一个完整的答案,但是我收到这个的一个具体情况是当试图访问一个“死亡”的对象,因为我试图使用autorelease:
netObjectDefinedInMyHeader = [[[MyNetObject alloc] init] autorelease];
所以举个例子,我实际上把这个作为一个对象传递给'notify'(把它注册为一个监听器,观察者,无论你喜欢什么成语),但是一旦通知被发送,它就已经死了,我会得到EXC_BAD_ACCESS。 将其更改为[[MyNetObject alloc] init]
并稍后释放它解决了错误。
这可能发生的另一个原因是,例如,如果您传入一个对象并尝试存储它:
myObjectDefinedInHeader = aParameterObjectPassedIn;
稍后当尝试访问myObjectDefinedInHeader时,可能会遇到麻烦。 使用:
myObjectDefinedInHeader = [aParameterObjectPassedIn retain];
可能是你需要的。 当然这些只是我遇到的一些例子,还有其他的原因,但是这些可以certificate是难以捉摸的,所以我提到它们。 祝你好运!
只是为了增加另一种情况发生:
我有这样的代码:
NSMutableString *string; [string appendWithFormat:@"foo"];
显然我忘了为string分配内存:
NSMutableString *string = [[NSMutableString alloc] init]; [string appendWithFormat:@"foo"];
修复了这个问题。
捕获EXC_BAD_ACCESSexception的另一种方法是在XCode 4+中使用静态分析器 。
使用Product> Analyze(shift + cmd + B)运行静态分析器。 点击分析仪生成的任何消息将覆盖源图上的图表,显示违规对象的保留/释放顺序。
使用“如果你没有分配或保留它,不释放它”的简单规则。
如何debuggingEXC_BAD_ACCESS
看看上面的链接,按照说的做….只是一些使用NSZombies快速指示
运行应用程序,并失败后(应显示“中断”,而不是“EXC_BAD_ACCESS”…检查控制台(运行>控制台)…应该有一个消息,现在告诉它试图访问什么对象。
-ben
我觉得在objc_exception_throw上设置一个断点很有用。 这样debugging器应该在得到EXC_BAD_ACCESS时中断。
说明可以在这里findDebuggingTechniques
我一直在debugging,并重构代码来解决过去四个小时的这个错误。 上面的post导致我看到了这个问题:
属性before:startPoint = [[DataPoint alloc] init]; startPoint = [DataPointList objectAtIndex:0];
。 。 。 x = startPoint.x – 10; // EXC_BAD_ACCESS
属性after:startPoint = [[DataPoint alloc] init]; startPoint = [[DataPointList objectAtIndex:0] retain];
再见EXC_BAD_ACCESS
希望你完成后发布“string”!
我忘了在init-Method中返回self …;)
这是一个很好的线索。 这是我的经验:我搞砸了属性声明的保留/分配关键字。 我说:
@property (nonatomic, assign) IBOutlet UISegmentedControl *choicesControl; @property (nonatomic, assign) IBOutlet UISwitch *africaSwitch; @property (nonatomic, assign) IBOutlet UISwitch *asiaSwitch;
我应该说的
@property (nonatomic, retain) IBOutlet UISegmentedControl *choicesControl; @property (nonatomic, retain) IBOutlet UISwitch *africaSwitch; @property (nonatomic, retain) IBOutlet UISwitch *asiaSwitch;
我只在尝试执行包含大数组的C方法时在iPhone上遇到了EXC_BAD_ACCESS。 模拟器能够给我足够的内存来运行代码,但不是设备(数组是一百万字符,所以这是一个有点过分!)。
EXC_BAD_ACCESS发生在方法的入口点之后,让我感到困惑了很长一段时间,因为它离数组声明很远。
也许别人可能会受益于我的几个小时的拉毛。
忘记从dealloc
取出一个未分配的指针。 我在UINavigationController的rootView上得到了exc_bad_access,但有时候却是这样。 我认为问题出在rootView,因为它在viewDidAppear {}中途崩溃。 事实certificate,只有在我用不好的dealloc发布的视图popup之后,就是这样了!
“EXC_BAD_ACCESS”[切换到进程330]没有可用的内存现在编程:不安全的调用malloc
我认为这是一个问题,我试图分配…不是我试图释放一个不分配的地方,哦,哦!
NSAssert()调用来validation方法参数对于追踪和避免传递nils来说非常方便。
我刚刚有这个问题。 对我来说,原因是删除了一个CoreDatapipe理对象,并尝试从另一个地方读取它。
我一直在debugging,并重构代码来解决过去四个小时的这个错误。 上面的post导致我看到了这个问题:
物业前:
startPoint = [[DataPoint alloc] init] ; startPoint= [DataPointList objectAtIndex: 0]; x = startPoint.x - 10; // EXC_BAD_ACCESS
物业后:
startPoint = [[DataPoint alloc] init] ; startPoint = [[DataPointList objectAtIndex: 0] retain];
再见EXC_BAD_ACCESS
非常感谢你的回答。 我一整天都在为这个问题苦苦挣扎。 你真棒!
只需添加
Lynda.com有一个梦幻般的DVD叫
iPhone SDK基本培训
而第6章第3课则是关于EXEC_BAD_ACCESS和僵尸工作。
这对我来说是很好理解的,不仅仅是错误代码,而且我怎样才能使用僵尸来获得更多关于发布对象的信息。
检查可能的错误
使用NSZombieEnabled。
要在您的应用程序中激活NSZombieEnabled工具:
select“项目”>“编辑活动可执行文件”以打开可执行文件窗口。 点击参数。 单击“要在环境中设置的variables”部分中的添加(+)button。 在Name列中inputNSZombieEnabled,在Value列中inputYES。 确保已选中NSZombieEnabled条目的复选标记。
我在iPhoneSDK上find了这个答案
我意识到这是前一段时间问的,但在阅读了这个线程之后,我find了XCode 4.2的解决scheme:Product – > Edit Scheme – > Diagnostics Tab – > Enable Zombie Objects
帮助我find一个消息被发送到一个释放对象。
我如何处理EXC_BAD_ACCESS
有时候我觉得当发生EXC_BAD_ACCESS错误时,xcode会在main.m类中显示错误,不会提供有关崩溃发生的信息(有时候)。
在那些时候,我们可以在Xcode中设置一个Exceptional Breakpoint,这样当exception被捕获时,将会放置一个断点,并直接贴近用户发生崩溃的地方
当你有无限recursion时,我认为你也可以有这个错误。 这是我的情况。
甚至有另一种可能性:在队列中使用块时,可能很容易发生的情况是您尝试访问另一个队列中的对象,此队列此时已被解除分配。 通常当你尝试发送一些东西到GUI。 如果你的exception断点被设置在一个陌生的地方,那么这可能是原因。
我知道了,因为我没有使用[self performSegueWithIdentifier:sender:]
和-(void) prepareForSegue:(UIstoryboardSegue *)
right
XCode 4及以上版本,使用仪器已经变得非常简单。 只要运行在仪器僵尸。 本教程对其进行了很好的解释: debuggingexc_bad_access错误xcode工具
创buildstring时不要忘记@
符号,因为NSStrings
会导致EXC_BAD_ACCESS
。
用这个:
@"Some String"
而不是:
"Some String"
PS – 通常当填充大量logging的array
内容时。