main.m中的EXC_BAD_ACCESS

3

突然间我在这一行遇到了EXC_BAD_ACCESS错误:

int retVal = UIApplicationMain(argc, argv, nil, nil);

这是代码:

这里是代码:

int main(int argc, char *argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, nil);
    [pool release];
    return retVal;
}

我甚至不知道从哪里开始寻找?

有人能帮忙吗?

4个回答

10

对于任何EXC_BAD_ACCESS错误,通常是尝试向已释放的对象发送消息。跟踪这些错误的最佳方法是使用NSZombieEnabled

它的工作原理是不释放对象,而是将其包装成“僵尸”,并在其中设置一个标志,表示它通常已被释放。这样,如果您再次尝试访问它,它仍然知道在出现错误之前它是什么样子的,有了这点信息,您通常可以回溯查看问题所在。

当调试器在任何有用的信息方面都失败时,它尤其有助于在后台线程中使用。

非常重要的一点是,您需要确保此功能仅在调试代码中而非发布代码中使用。因为没有任何东西被释放,您的应用程序将泄漏无穷无尽。为了提醒我注意这个问题,我将以下日志放在我的appdelegate中:

if(getenv("NSZombieEnabled") || getenv("NSAutoreleaseFreedObjectCheckEnabled"))
  NSLog(@"NSZombieEnabled/NSAutoreleaseFreedObjectCheckEnabled enabled!");

3
目前最好的方法是使用Instruments中的Zombies模板。它比调试器提供更多信息,即整个已崩溃(或任何其他)对象的历史记录。 - Peter Hosey
关于 NSZombieEnabled 的链接已失效 :( - Tõnu Samuel

4
EXC_BAD_ACCESS是一种信号,表明您试图访问已被释放或不存在的内存中的变量。由于它在释放自动释放池后出现,这意味着您可能过度释放了具有挂起自动释放池的变量,因此当自动释放池被排空时,该变量不再存在于释放状态。有许多现有的问题解决了这个问题,其中的主要问题是这个。请参考:这个问题

1

EXC_BAD_ACCESS通常表示您已经超出了内存释放。您可以使用Xcode中的“构建和分析”命令来帮助跟踪此问题。我还建议在代码中添加断点和日志语句以隔离错误。


0

我曾经遇到过这个问题,可能是因为你正在使用苹果最新的 main.m 文件,它执行了以下操作:

NSString * appDelegateClassName;

@autoreleasepool {
    // Setup code that might create autoreleased objects goes here.
    appDelegateClassName = NSStringFromClass([AppDelegate class]); }

return UIApplicationMain(argc, argv, nil, appDelegateClassName);

我不使用ARC,而是将代码更改为他们以前使用的代码:

@autoreleasepool
{
    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}

看起来这个可以工作!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接