0

这是我的第一篇文章。我为错误道歉。

我有一个可以修复的崩溃,但我不明白为什么它首先会崩溃。我试图将代码简化为使其崩溃的基本要素:

GCFTile *currentTile;
NSInteger repeatCount = 0;
do {

    currentTile = self.remainingTilesArray[0];
    if (repeatCount == 0) {

        [self.remainingTilesArray removeObjectAtIndex:0];
        [self.remainingTilesArray addObject:currentTile];
    }
    void (^myBlock)() = ^{

        currentTile;
    };
    repeatCount++;
} while (repeatCount == 1);

我正在使用 Xcode 4.5.2、iOS 5、ARC。此外,仅当 LLVM 编译器优化设置为“快速”或更高时,它才会崩溃。

上面的代码将从 NSMutableArray 中获取和删除一个对象,将其放回原处,然后从数组中获取另一个对象。上面的代码将运行而不会崩溃,但是如果我稍后扫描数组中的所有元素(例如,从不同的方法),那么它就会崩溃。看起来随机内存地址被添加到数组中(可能来自上面对 addObject 的调用)。

上面的块应该什么都不做,但如果我改变它,那么以后就不会崩溃了。(例如,空块 = 没有崩溃。不要将块声明为“myBlock” = 没有崩溃。)如果我不重复循环,就没有崩溃。如果我不重新添加对象,则不会发生崩溃。如果我使用 __block 或在 do 循环中声明 currentTile,则不会发生崩溃。

我知道块是“堆栈本地的”,但这个块没有做任何事情!它运行良好,无需编译器优化。

知道发生了什么吗?

编辑(12-5-12):有人要求提供崩溃日志。我正在模拟器中运行,所以我不知道如何获得它。但这里有一些来自 Debug Navigator 的内容:

#0  0x0140409b in objc_msgSend ()
#1  0x00010931 in __33-[GCFGame checkThatTilesAreValid]_block_invoke_0 at /Users/geoffrey2/personal/projects/Color Fever/Color Fever/GCFGame.m:54
#2  0x01cb24a5 in __NSArrayEnumerate ()
#3  0x01cb2026 in -[NSArray enumerateObjectsWithOptions:usingBlock:] ()
#4  0x01cb1f35 in -[NSArray enumerateObjectsUsingBlock:] ()
#5  0x000108f6 in -[GCFGame checkThatTilesAreValid] at /Users/geoffrey2/personal/projects/Color Fever/Color Fever/GCFGame.m:52

并且主窗口显示了这一点(加上更多行):

libobjc.A.dylib`objc_msgSend:
0x140408c:  movl   8(%esp), %ecx
0x1404090:  movl   4(%esp), %eax
0x1404094:  testl  %eax, %eax
0x1404096:  je     0x14040e8                 ; objc_msgSend + 92
0x1404098:  movl   (%eax), %edx
0x140409a:  pushl  %edi
0x140409b:  movl   8(%edx), %edi

错误是EXC_BAD_ACCESS(code=2, adddress=0x9).

4

0 回答 0