只要我一次逐步执行说明,它还将调试并运行。一旦让它再次运行,我就会碰到
EXC_BAD_ACCESS
信号。在这种情况下,它恰好是加速度计代码中的错误。它不会在模拟器中执行,这就是为什么它不会引发任何错误的原因。但是,它将在部署到设备后立即执行。该问题的大多数答案都涉及一般的
EXC_BAD_ACCESS
错误,因此,我将保留所有这些内容,以解决可怕的Bad Access错误。EXC_BAD_ACCESS
通常是由于非法内存访问而引发的。您可以在下面的答案中找到更多信息。您之前遇到过
EXC_BAD_ACCESS
信号,如何处理?#1 楼
根据您的描述,我怀疑最可能的解释是您的内存管理有一些错误。您说您已经从事iPhone开发工作了几周,但对于您是否对Objective C有所了解却不是。如果您来自其他背景,则在真正内化内存管理规则之前可能要花一些时间-除非您对此有重点,否则请记住。通常是静态alloc方法,但还有一些其他方法)或copy方法,您也拥有该内存,并且必须在完成后释放它。包括工厂方法在内的任何其他内容(例如[NSString stringWithFormat]
),那么您将拥有一个自动释放引用,这意味着它可能会在将来的某个时候由其他代码释放-因此至关重要的是,如果您需要将其保留在即时函数之外您保留它。如果不这样做,则在进行模拟器测试期间,内存可能会在使用时保持分配状态,或者被释放但同时仍然有效,但是更有可能被释放并在设备上运行时显示为访问错误。 跟踪这些问题的最佳方法也是一个好主意(即使没有明显的问题),最好是在Instruments工具中运行该应用程序,尤其是使用Leaks选项。 >
#2 楼
EXC_BAD_ACCESS的主要原因是试图访问已释放的对象。要查找如何解决此问题,请阅读以下文档:
DebuggingAutoReleasePool
不要以为您是“释放自动释放的对象”,这将适用于您。
此方法非常有效。我一直在使用它,并取得了巨大的成功!代码。我很确定内存泄漏与EXC_BAD_ACCESS无关。泄漏的定义是您不再有权访问的对象,因此无法调用它。
UPDATE:
我现在使用Instruments来调试Leaks。在Xcode 4.2中,选择“产品”->“配置文件”,然后在Instruments启动时选择“僵尸”。
评论
该旁注非常重要。泄漏不会导致EXC_BAD_ACCESS(它们还有其他问题)。我写这篇文章是为了消除对EXC_BAD_ACCESS的误解loufranco.com/blog/files/Understanding-EXC_BAD_ACCESS.html
–卢佛朗哥
10 Jul 23 '11:57
Xcode中的僵尸工具很棒!我在3分钟而不是几小时内找到了罪魁祸首。
–阿拉姆·科恰良(Aram Kocharyan)
2012年3月2日在4:50
以上答案中的链接不可用。显示404找不到错误。
– Tejas
17年1月3日在12:00
#3 楼
EXC_BAD_ACCESS信号是将无效指针传递给系统调用的结果。我今天早些时候在OS X上得到了一个测试程序-我将一个未初始化的变量传递给pthread_join()
,这是由于打字错误造成的。应该仔细检查传递给系统调用的所有缓冲区指针。完全提高编译器的警告级别(使用gcc时,请使用-Wall
和-Wextra
选项)。在模拟器/调试器上启用尽可能多的诊断。#4 楼
以我的经验,这通常是由非法的内存访问引起的。检查所有指针,尤其是对象指针,以确保它们已初始化。如果使用的是MainWindow.xib文件,请确保已正确设置并具有所有必要的连接。如果单步执行不会发生,请尝试使用NSLog()语句查找错误:在代码中撒满代码,四处移动,直到找出导致错误的行。然后在该行上设置一个断点并运行程序。当您达到断点时,请检查所有变量以及其中的对象,以查看是否有什么不符合您的期望。我尤其要注意那些对象类不是您所期望的变量。如果一个变量应该包含一个UIWindow但其中包含一个NSNotification,则当调试器不运行时,相同的基础代码错误可能以不同的方式表现出来。#5 楼
我只花了几个小时跟踪EXC_BAD_ACCESS,发现NSZombies和其他env var似乎什么都没告诉我。NSLog(@"Some silly log message %@-%@");
固定在
NSLog(@"Some silly log message %@-%@", someObj1, someObj2);
#6 楼
苹果开发人员计划的任何参与者都可以使用2010 WWDC视频。有一个很棒的视频:“会议311-使用仪器进行高级内存分析”,其中显示了一些在仪器中使用僵尸并调试其他内存问题的示例。 br />
有关登录页面的链接,请单击此处。
#7 楼
不是一个完整的答案,而是我收到的一个具体情况是,由于我尝试使用自动释放,试图访问“死”的对象时:netObjectDefinedInMyHeader = [[[MyNetObject alloc] init] autorelease];
因此,例如,我实际上将其作为“通知”的对象传递(将其注册为侦听器,观察者,无论您喜欢哪种惯用法),但是一旦发送通知,它就已经死了,我将获得EXC_BAD_ACCESS。将其更改为[[MyNetObject alloc] init]
并在以后适当时释放它可以解决该错误。 发生这种情况的另一个原因是,例如,如果您传入一个对象并尝试存储它:
myObjectDefinedInHeader = aParameterObjectPassedIn;
myObjectDefinedInHeader可能会引起麻烦。使用:myObjectDefinedInHeader = [aParameterObjectPassedIn retain];
可能是您需要的。当然,这些只是我遇到的例子中的几个,还有其他原因,但是这些原因可能难以捉摸,因此我将其提及。祝你好运!
#8 楼
只是增加了可能发生这种情况的另一种情况:我有以下代码:
:
NSMutableString *string;
[string appendWithFormat:@"foo"];
解决了这个问题。
评论
这不会对我造成任何错误,因为将字符串初始化为nil并使用null对象模式对nil调用方法没有任何作用。
– Liron Yahdav
2014年11月14日在18:28
#9 楼
在异常发生之前捕获EXC_BAD_ACCESS异常的另一种方法是在XCode 4+中使用静态分析器。分析器生成的消息将在源上覆盖一个图表,该图表显示有问题的对象的保留/释放顺序。#10 楼
我发现在objc_exception_throw上设置断点很有用。这样,当您获得EXC_BAD_ACCESS时,调试器应该会中断。指令可以在这里找到DebuggingTechniques
#11 楼
使用“如果不分配或保留它,不要释放它”的简单规则。评论
通过“ ...复制它...”扩展该规则,您应该可以。
–直到
2012年6月26日19:53
#12 楼
如何调试EXC_BAD_ACCESS检查上面的链接,然后按说做...。显示“已中断”而不是“ EXC_BAD_ACCESS” ...检查控制台(运行>控制台)...现在应该有一条消息,告诉它正在尝试访问的对象。
-Ben
#13 楼
最近四个小时,我一直在调试和重构代码以解决此错误。上面的帖子使我看到了这个问题:之前的属性:
startPoint = [[DataPoint alloc] init];
startPoint = [DataPointList objectAtIndex:0];
。
。
。
x = startPoint.x-10; // EXC_BAD_ACCESS
之后的属性:
startPoint = [[DataPoint alloc] init];
startPoint = [[DataPointList objectAtIndex:0]保留];
再见EXC_BAD_ACCESS
评论
我犯了类似的错误。我忘记找回导致崩溃的实例,我花了几个小时才弄清楚。你的经历让我发现了我的。谢谢!
– David.Chu.ca
2010年4月12日下午4:19
#14 楼
希望您在完成后释放“字符串”!#15 楼
我忘了在init-Method中返回自己...;)评论
这应该是编译时警告/错误,而不是运行时期间的EXC_BAD_ACCESS。
–stigi
2014年7月29日在9:03
#16 楼
这是一个很好的线程。这是我的经验:我搞砸了属性声明中的keep / assign关键字。我说:@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;
评论
奇怪,为什么您需要保留IBOutlet?他们的管理为您自动完成。
– jv42
2011年1月13日在16:09
#17 楼
我仅在尝试执行包含大数组的C方法时在iPhone上遇到EXC_BAD_ACCESS。模拟器能够给我足够的内存来运行代码,但不能给设备运行(数组是一百万个字符,因此有点多余!)。EXC_BAD_ACCESS刚好在方法的入口点之后发生,并且让我困惑了很长时间,因为它离数组声明不远。我几个小时的脱发。
#18 楼
忘记从dealloc
中取出未分配的指针。我在UINavigationController的rootView上获得了exc_bad_access,但仅在某些时候。我认为问题出在rootView中,因为它在其viewDidAppear {}中途崩溃了。原来只有在弹出带有不良dealloc {}版本的视图后才发生,仅此而已!打电话给malloc 我以为这是我要分配的问题...而不是我要发行非分配的问题,D'oh!
#19 楼
我如何处理EXC_BAD_ACCESS有时,我觉得当抛出EXC_BAD_ACCESS错误时,xcode将在main.m类中显示该错误,而没有提供崩溃发生位置的额外信息(有时)。 >
在那个时候,我们可以在Xcode中设置一个异常断点,以便在捕获异常时放置一个断点,并将直接提示用户该行发生了崩溃。 br />
#20 楼
验证方法参数的NSAssert()调用非常便于跟踪并避免传递nil。#21 楼
我只是有这个问题。对我来说,原因是删除Core Data管理的对象,然后尝试从另一个地方读取它。#22 楼
最近四个小时,我一直在调试和重构代码以解决此错误。上面的帖子使我看到了问题:之前的属性:
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
非常感谢您的回答。我整天都在为这个问题而苦苦挣扎。太棒了!
评论
您不是立即覆盖startPoint吗?我认为您根本不需要第一行。
– toxaq
10 Sep 24'5:36
如果您要立即用另一个变量覆盖,则绝对不需要分配和初始化变量。您只是在第一次分配中泄漏了对象。
–dreamlax
2010-10-19 20:35
#23 楼
只需添加Lynda.com就有一张很棒的DVD,名为
iPhone SDK基础培训
和第6章,第3课都是关于EXEC_BAD_ACCESS以及如何与Zombies一起使用。 />
#24 楼
要检查可能是什么错误,请使用NSZombieEnabled。要在应用程序中激活NSZombieEnabled工具:
选择“项目”>“将活动可执行文件编辑为”打开可执行文件的“信息”窗口。
单击“参数”。
在“要在环境中设置的变量”部分中单击添加(+)按钮。
在“名称”列中输入NSZombieEnabled,然后在“是”中输入YES。 “值”列。
确保已选中NSZombieEnabled条目的复选标记。
我在iPhoneSDK上找到了此答案
#25 楼
我意识到这是在一段时间前被问到的,但是在阅读了此线程之后,我找到了XCode 4.2的解决方案:产品->编辑方案->诊断选项卡->启用僵尸对象
已帮助我发现一条消息正在发送到已释放的对象。
#26 楼
当您进行无限递归时,我认为您也可能会遇到此错误。对我来说就是这样。#27 楼
还有另一种可能性:在队列中使用块,很容易发生这种情况,您尝试访问另一个队列中的对象,该对象此时已被取消分配。通常,当您尝试将某些内容发送到GUI时。如果将异常断点设置在一个陌生的地方,则可能是原因。
#28 楼
我明白了,因为我没有使用[self performSegueWithIdentifier:sender:]
和-(void) prepareForSegue:(UIstoryboardSegue *)
对#29 楼
创建字符串时不要忘记@
符号,将C-strings
视为NSStrings
会导致EXC_BAD_ACCESS
。使用此: :
@"Some String"
PS-通常在用大量记录填充
array
的内容时。
评论
我有一些加速度计采样代码,这些代码对我的应用而言并不重要,在删除之后,它消除了错误的访问错误。考虑到模拟器没有加速度计,这很有意义。我确实很奇怪,在导致此错误之前,这个代码已经存在了一周,没有被触及过...
–Héctor Ramos
08年11月30日在0:31
我是Objective-C的新手,所以我的大部分问题都应该来自内存管理。在使用C ++几年后,最近三,四年来我一直在使用Java,因此我对内存管理感到生疏。感谢您的回答!
–Héctor Ramos
08年11月30日,0:32
没问题-很高兴您修复了它。内存管理并非难事之上-您只需要确保学习规则并养成良好的习惯即可。
– philsquared
08年11月30日在1:14
我遇到的问题似乎完全是因为过于激进地释放了我创建的字符串(或诸如此类)。我仍然不确定要发布什么内容和发布时间,但仍不确定100%,但Phil的回答肯定有帮助。
–pluckyglen
09年5月26日下午4:37
如果我正确地遵循了cmculloh,是的,这是正确的做法。您不拥有objectAtIndex返回的对象。
– philsquared
09年9月11日在12:17