收到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内容时。