“EXC_BAD_ACCESS:无法恢复以前选择的帧” - 堆栈变量未被清除

时间:2012-02-15 22:32:05

标签: iphone xcode xcode4.2 internal

参考问题here

该主题提供的解决方案包括:

  1. 要知道你声明的变量的位置和数量,这将在堆栈中进行。
  2. 如果需要,请禁用Guard Malloc。
  3. 另外,一般来说: 3.确保释放一个实际为内存分配的变量!!

    我没有上述问题。我在函数中使用的堆栈分配变量非常少,比如说每个函数中有2-3个变量。但是因为函数在循环中被多次调用,所以它似乎会触发异常。

    这里是踢球者,这不仅仅是静态分配的变量,而是堆上的东西!我在自动发布的NSNumber变量声明中得到了页面错误,我在循环中使用了几个变量,以及我在每次调用时都会在函数范围内分配和释放的字典。 / p>

    那么为什么会发生这种情况,以及为什么堆变量会受到影响?我根本没有得到它,请对此有所了解。 :)

    我在IOS5上使用XCode 4.2,iPhone / iPad模拟器。

    谢谢!

    此致 开发

    编辑:示例代码
    - (void)doSomething {
    NSInteger fun = 3;
    NSInteger time = 4;
    NSInteger overload = fun*time;
    NSString *string = [NSString stringWithFormat:@"%d",overload];
    NSObject *myCustomObject = [[NSObject alloc] init];
    [myCustomDictionary setObject:myCustomObject forKey:string];
    [myCustomObject release];
    //myCustomDictionary is an iVar, alloced in the class's init method, and released in dealloc and not touched anywhere in between
    }
    //doSomething gets called several times through the course of execution as the state of the view changes, the user interacts with it etc, often 2-3 times during one state change.

    代码是故意模糊的,但与此同时,它完全像样本中一样简单。与整个项目中的其余代码一样。几个函数,每个函数都做了少量的工作,就像这个函数一样非常自包含。

    之前我遇到过EXC_BAD_ACCESS问题,此时提到了this问题。但是在我的情况下,我没有在循环中在堆栈上创建多个变量,它们是由一个函数重复创建的,该函数在执行过程中被多次调用。理想情况下,变量应该在函数范围的末尾被破坏。不知道为什么没有发生这种情况。

    无论如何,要解决这个问题并防止多次分配发生,我最终将我的堆栈分配变量声明为全部static。这是不好的做法,但这正是我必须做的才能让它发挥作用。它一直在工作,直到我最终面对“doSomething”功能的问题。

    所以“doSomething”的难点在于我没有创建堆栈分配的变量,而是堆积的东西。所以我首先开始在NSInteger变量上获得EXC_BAD_ACCESS,此时我尝试再次修复它,将它们声明为静态。它工作,但现在EXC_BAD_ACCESS开始发生在自动释放的变量上,最后是自定义分配的变量 - 这是我被难倒的时候。我一直遵循内存管理的所有规则,而且我的堆栈AND堆变量遍布我。如果它只是堆东西,或者在循环中堆叠东西,我可以理解在某处出现了错误。但是在这里,它们都不是,这些是完全无辜的变量在一个函数中被分配在一个不在循环中调用的函数中,而常规的自动释放变量从来没有从代码中的另一个地方获得保留或释放。更糟糕的是,失败点是随机的 - 不仅在这个函数中,而且实际上每个在项目执行过程中被调用的次数都是随机的。

    Edit2:原来,在这种情况下,这是我的错。详情请见我的回答。抱歉浪费了人们的时间。 :\

3 个答案:

答案 0 :(得分:1)

如果没有看到整个堆栈跟踪,我们无法真正帮助您。 EXC_BAD_ACCESS对于排除故障并不意味着我们需要知道异常是什么。

根据我的经验,当你没有得到堆栈时,它意味着你是双重释放。僵尸是找到双重释放的方式。

转到:Product -> Profile,然后从列表中选择“Zombies”。 运行应用程序并执行导致崩溃的任何任务,如果问题是双重释放,则会出现弹出窗口。选择弹出窗口中的箭头,它会准确告诉您正在双重释放的对象,并显示保留周期。

答案 1 :(得分:0)

在您的问题中没有发布任何代码,并且看到您正在使用iOS 5和Xcode 4.2,我最好的建议是,在Xcode中,转到Edit>Refactor>Convert to Objective-C ARC并挥手告别所有内存管理问题。

ARC为您完成所有内存管理。您不需要保留,释放或编写dealloc方法。在大多数情况下,您不必担心内存管理。你将留下神秘的EXC_BAD_ACCESS崩溃。它的工作方式非常有效。编译器为您输入保留和发布,然后进行优化。你甚至不必看到代码。

答案 2 :(得分:0)

啊,我不相信这一点。

早先使用堆栈分配的NSInteger变量所面临的问题仍然存在,但在这种情况下,这完全是我的错。

“doSomething”是一系列事件的一部分,由于我的一些愚蠢的疏忽,最终会循环多次,正确而且应该如此,导致应用程序运行内存不足。无论是使用堆栈变量还是使用malloced的堆栈变量,无限循环,它都会以某种方式崩溃。 :)

所以崩溃是完全公平的,只是在这种情况下与以前的问题混淆了,结果证明是不相关的。 :(

抱歉浪费每个人的时间。