当前位置:  开发笔记 > 前端 > 正文

收到EXC_BAD_ACCESS信号

如何解决《收到EXC_BAD_ACCESS信号》经验,为你挑选了10个好方法。

将应用程序部署到设备时,程序将在几个周期后退出并出现以下错误:

Program received signal: "EXC_BAD_ACCESS".

该程序在iPhone模拟器上运行没有任何问题,只要我逐步执行一个指令,它也将调试和运行.一旦我让它再次运行,我就会EXC_BAD_ACCESS发出信号.

在这种特殊情况下,它恰好是加速度计代码中的错误.它不会在模拟器中执行,这就是它没有抛出任何错误的原因.但是,它会在部署到设备后执行.

这个问题的大部分答案都是针对一般EXC_BAD_ACCESS错误的,所以我会把这个问题保留为可怕的Bad Access错误.

EXC_BAD_ACCESS通常由于非法内存访问而被抛出.您可以在下面的答案中找到更多信息.

EXC_BAD_ACCESS以前遇到过这个信号吗,你是怎么处理它的?



1> philsquared..:

根据您的描述,我怀疑最可能的解释是您的内存管理存在一些错误.你说你已经在iPhone开发工作了几个星期,但不是你是否对Objective C有一般经验.如果你来自另一个背景,你可能需要一段时间才真正内化内存管理规则 - 除非你提出一个重点.

请记住,从分配函数(通常是静态alloc方法,但还有其他一些方法)或复制方法获得的任何内容,您也拥有内存,并且必须在完成后释放它.

但是如果你从包括工厂方法在内的任何其他方面得到回报(例如[NSString stringWithFormat])那么你将有一个自动释放引用,这意味着它可以在将来的某个时间通过其他代码发布 - 所以如果你需要它是至关重要的保持它超越你保留它的直接功能.如果不这样做,内存可能会在您使用它时保持分配状态,或在模拟器测试期间被释放但巧合仍然有效,但在设备上运行时更有可能被释放并显示为错误的访问错误.

跟踪这些事情的最佳方式,无论如何都是一个好主意(即使没有明显的问题)是在"工具"工具中运行应用程序,尤其是使用"泄漏"选项.


没问题 - 很高兴你修好了.内存管理并不是很难掌握 - 你只需要确保你学习规则并养成良好的习惯.
我有一些对我的应用程序不重要的加速度计采样代码,在删除后,消除了错误的访问错误.考虑到模拟器没有加速度计,这是有道理的.我觉得奇怪的是,这段代码存在,未触动过一周,然后才导致此错误...

2> bentford..:

EXC_BAD_ACCESS的一个主要原因是尝试访问已发布的对象.

要了解如何解决此问题,请阅读本文档: DebuggingAutoReleasePool

即使您认为自己并未"发布自动发布的对象",这也适用于您.

这种方法非常有效.我一直使用它取得了巨大的成功!

总之,这解释了如何使用Cocoa的NSZombie调试类和命令行"malloc_history"工具来准确找到代码中已访问的已发布对象.

边注:

运行仪器和检查泄漏无助于排除EXC_BAD_ACCESS故障.我很确定内存泄漏与EXC_BAD_ACCESS无关.泄漏的定义是您无法再访问的对象,因此您无法调用它.

更新: 我现在使用Instruments来调试泄漏.从Xcode 4.2中选择Product-> Profile,当Instruments启动时,选择"Zombies".


该旁注非常重要.泄漏不会导致EXC_BAD_ACCESS(他们有其他问题).我写这篇文章试图澄清有关EXC_BAD_ACCESS的错误观念http://loufranco.com/blog/files/Understanding-EXC_BAD_ACCESS.html
Xcode中的僵尸工具非常棒!我发现罪魁祸首是3分钟而不是数小时.
@LouFranco:你的帖子的链接应该是接受的答案.非常好的解释,干得好!

3> Adam Rosenfi..:

EXC_BAD_ACCESS信号是将无效指针传递给系统调用的结果.我今天早些时候在OS X上得到了一个测试程序 - 我正在传递一个未初始化的变量pthread_join(),这是由于早期的拼写错误.

我不熟悉iPhone开发,但你应该仔细检查你传递给系统调用的所有缓冲区指针.一直调试编译器的警告级别(使用gcc,使用-Wall-Wextra选项).在模拟器/调试器上启用尽可能多的诊断.



4> Brent Royal-..:

根据我的经验,这通常是由非法内存访问引起的.检查所有指针,尤其是对象指针,以确保它们已初始化.确保您的MainWindow.xib文件(如果您使用的话)已正确设置,并具有所有必要的连接.

如果没有任何纸上检查变成任何东西,并且在单步执行时不会发生,请尝试使用NSLog()语句找到错误:将代码洒在它们上面,移动它们直到找出引起它的行错误.然后在该行上设置断点并运行程序.当你点击断点时,检查所有变量及其中的对象,看看是否有任何看起来不像你期望的那样.我会特别留意那些对象类是你没想到的变量.如果一个变量应该包含一个UIWindow但是它中有一个NSNotification,那么当调试器没有运行时,相同的底层代码错误可能以不同的方式表现出来.



5> Scott Heaber..:

我只花了几个小时跟踪一个EXC_BAD_ACCESS,发现NSZombies和其他env vars似乎没有告诉我任何事情.

对我来说,这是一个带有格式说明符但没有传递args的愚蠢的NSLog语句.

NSLog(@"Some silly log message %@-%@");

固定的

NSLog(@"Some silly log message %@-%@", someObj1, someObj2);



6> Rob..:

不是一个完整的答案,但我收到这个的一个特定情况是,当我尝试使用自动释放时,试图访问"死"的对象:

netObjectDefinedInMyHeader = [[[MyNetObject alloc] init] autorelease];

因此,例如,我实际上将此作为对象传递给'通知'(将其注册为监听器,观察者,您喜欢的任何习惯用法),但是一旦发送通知就已经死了,我将获得EXC_BAD_ACCESS.将其更改为[[MyNetObject alloc] init]并在适当的时候释放它可以解决错误.

这可能发生的另一个原因是,例如,如果您传入一个对象并尝试存储它:

myObjectDefinedInHeader = aParameterObjectPassedIn;

稍后当尝试访问myObjectDefinedInHeader时,您可能会遇到麻烦.使用:

myObjectDefinedInHeader = [aParameterObjectPassedIn retain];

可能是你需要的.当然,这只是我遇到的几个例子,还有其他原因,但这些可能难以理解,所以我提到它们.祝好运!



7> Jonah..:

Apple WWDC视频可供Apple开发者计划的任何参与者使用.这是一个很棒的视频:"会话311 - 使用乐器进行高级内存分析",其中显示了在仪器中使用僵尸和调试其他内存问题的一些示例.

有关登录页面的链接,请单击此处.



8> gnuchu..:

只是为了增加另一种情况:

我有代码:

NSMutableString *string;
[string   appendWithFormat:@"foo"];

显然我忘了为字符串分配内存:

NSMutableString *string = [[NSMutableString alloc] init];
[string   appendWithFormat:@"foo"];

解决了这个问题.



9> 小智..:

我发现在objc_exception_throw上设置断点很有用.这样,当您获得EXC_BAD_ACCESS时,调试器应该会中断.

可以在此处找到有关DebuggingTechniques的说明



10> ericsoco..:

在它们发生之前捕获EXC_BAD_ACCESS异常的另一种方法是静态分析器,在XCode 4+中.

使用Product> Analyze(shift + cmd + B)运行静态分析器.单击分析器生成的任何消息将覆盖源上的图表,显示违规对象的保留/释放顺序.

在此输入图像描述

推荐阅读
mobiledu2402852413
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有