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

Program received signal: "EXC_BAD_ACCESS".

程序在iPhone模拟器上运行没有任何问题,只要我一次执行一个指令,它也会调试和运行。一旦我让它再次运行,我将击中EXC_BAD_ACCESS信号。

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

这个问题的大多数答案都处理一般的EXC_BAD_ACCESS错误,因此我将保留这个选项,作为可怕的坏访问错误的统称。

EXC_BAD_ACCESS通常是非法内存访问的结果。你可以在下面的答案中找到更多信息。

您以前遇到过EXC_BAD_ACCESS信号吗?您是如何处理它的?


当前回答

再补充一下

Lynda.com有一个很棒的DVD叫

iPhone SDK基本培训

第6章第3课是关于EXEC_BAD_ACCESS和使用僵尸的。

这对我来说是很好的理解,不仅是错误代码,而且我如何使用僵尸来获得更多关于释放对象的信息。

其他回答

在EXC_BAD_ACCESS异常发生之前捕捉异常的另一种方法是XCode 4+中的静态分析器。

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

如果您正在使用自定义字体,并且以编程方式实例化它们,则如果您之前没有在运行时注册字体,则会发生此错误。

为了确保是这样,Xcode控制台将打印如下内容:

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x1d8)
    frame #0: 0x0000000180f969cc CoreText`CTFontGetClientObject + 12
...

or

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
    frame #0: 0x000000012341c10e CoreFoundation`CFRelease.cold.1 + 14
    frame #1: 0x00000001232ed7bd CoreFoundation`CFRelease + 77
    frame #2: 0x0000000128136990 libGSFont.dylib`GSFontGetExtraData + 112
    frame #3: 0x0000000135bc8958 UIFoundation`-[UIFont lineHeight] + 9
    frame #4: 0x00000001340149f3 UIKitCore`-[UILabel intrinsicContentSize] + 331
...

要注册自定义字体并解决该问题,可以签出此解决方案:https://stackoverflow.com/a/69756114/3701102

从你的描述中,我怀疑最有可能的解释是你在内存管理中出现了一些错误。你说你已经在iPhone开发上工作了几个星期,但没有说你是否对Objective C有一般的经验。如果你来自其他背景,在你真正内化内存管理规则之前可能需要一段时间——除非你把它说得很重要。

记住,你从分配函数(通常是静态的alloc方法,但也有一些其他方法)或复制方法获得的任何东西,你也拥有内存,当你完成时必须释放它。

But if you get something back from just about anything else including factory methods (e.g. [NSString stringWithFormat]) then you'll have an autorelease reference, which means it could be released at some time in the future by other code - so it is vital that if you need to keep it around beyond the immediate function that you retain it. If you don't, the memory may remain allocated while you are using it, or be released but coincidentally still valid, during your emulator testing, but is more likely to be released and show up as bad access errors when running on the device.

追踪这些东西的最好方法,也是一个好主意(即使没有明显的问题)是在Instruments工具中运行应用程序,特别是带有Leaks选项。

这是一个很好的帖子。以下是我的经验:我在属性声明中搞砸了retain/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;

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

If none of that on-paper checking turns anything up, and it doesn't happen when single-stepping, try to locate the error with NSLog() statements: sprinkle your code with them, moving them around until you isolate the line that's causing the error. Then set a breakpoint on that line and run your program. When you hit the breakpoint, examine all the variables, and the objects in them, to see if anything doesn't look like you expect.I'd especially keep an eye out for variables whose object class is something you didn't expect. If a variable is supposed to contain a UIWindow but it has an NSNotification in it instead, the same underlying code error could be manifesting itself in a different way when the debugger isn't in operation.