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