0

私の iPhone ゲームでは、ios 4.0 シミュレーターで実行するとすべて正常に動作します。ただし、5.0 シミュレーターまたは 5.0 以降のデバイスで実行すると、アプリが最初のレベルでクラッシュし、エラーが発生します。

キャッチされていない例外 'NSGenericException' が原因でアプリを終了しています。理由:
*** コレクション <__NSArrayM: 0x1416eea0> が列挙中に変更されました。
*** First throw call stack:
(0x1d6a052 0x20d0d0a 0x1d69c21 0x6f8e 0x8bd48 0x94020 0xba169 0xbcee4 0x85a2db 0x85a1af 0x1d3e966 0x1d3e407 0x1ca17c0 0x1ca0db4 0x1ca0ccb 0x2702879 0x270293e 0x90fa9b 0x1f31 0x1eb5 0x1)
terminate called throwing an exception(lldb)

問題をこのコードに絞り込んだと思います。問題が for ループ内のオブジェクトを削除していることは理解していますが、解決策を見つけられないようです。

これが私のコードです:

//remove the projectile

for (CCSprite *projectile in projectilesToDelete) {
    [_projectiles removeObject:projectile];
    [self removeChild:projectile cleanup:YES];
}       
[projectilesToDelete release];

//remove the projectile

for (CCSprite *targetDel in targetsToDelete) {  
    targetDel.position = ccp(-2000, -2000);
    [self removeChild:targetDel cleanup:YES];
    [_targets removeObject:targetDel];
}                        
[targetsToDelete release];

助けてください、過去数日間理解しようとしてきました。

4

2 に答える 2

2

要するに、式:

for (OBJ * VAR in COLLECTION) {

Fast Enumerationと呼ばれる手法を使用します。ここで何が起こるかというと、コンパイラはスタックに隠しバッキング ストレージを挿入し、列挙可能な型から要素のコレクションを要求します。一度に多くのオブジェクトを取得して反復処理するCOLLECTIONため、スタック領域とコレクションが同期しなくなる可能性があるため、列挙中にコンテナー ( ) を変更するとエラーになります。

回避策は、列挙しているものを変更するときに高速な列挙を避けることです-それか、場合によってはコピーを列挙することができます。標準for(i;c;e)ループは高速反復を使用しませんが、for(in)使用します。


高速列挙エラーを回避するためにプログラムを変更する 1 つの方法は次のとおりです。

// remove the projectile
while (projectilesToDelete.count) {
    CCSprite * projectile = projectilesToDelete[0];
    [_projectiles removeObject:projectile];
    [self removeChild:projectile cleanup:YES];
}
[projectilesToDelete release];

// remove the projectile
while (targetsToDelete.count) {
    CCSprite * targetDel = targetsToDelete[0];
    targetDel.position = ccp(-2000, -2000);
    [self removeChild:targetDel cleanup:YES];
    [_targets removeObject:targetDel];
}
[targetsToDelete release];
于 2012-08-27T06:37:44.810 に答える
1

あなたのコードの問題は、これを考慮してください..... projectilesToDelete配列には3つの要素(A、B、C)があります...

最初の反復では、removeObject(A).. で配列カウントが 2 になります。つまり、配列の内容は (B, C) になりますが、3(B,C, Nil) と見なされます。

そのため、列挙中に配列が変更されました。したがって、例外が発生します。

コードをこれに変更します

// get array length
int count = projectilesToDelete. length;

// iterate through the array    
for (int iter = 0; iter < count; inter++) 
{
     CCSprite *projectile = projectilesToDelete [iter];

     [_projectiles removeObject:projectile];

     [self removeChild:projectile cleanup:YES];

      // decrement count
      count--;
      iter--;
} 
于 2012-08-27T06:29:26.913 に答える