2011-02-11 12 views
4

私のコードにはforというループが1つあります。私はNSMutableArrayを埋めるためにしようとしていますが、これが行われているものではありません。このforループを使用してiOSの「キャッチされていない例外によるアプリケーションの終了」

Terminating app due to uncaught exception 'NSRangeException', reason: '-[NSMutableArray objectAtIndex:] index 2 beyond bounds [0 .. 1]' Call stack at first throw: 

:このforループの実行は、私のアプリケーションのクラッシュを継続し、コンソールに次のメッセージを出力します 。

+0

いくつかのコードが役に立ちます。 –

+0

あなたはこのクラッシュが起こる場所に機能を投稿しますか? – Max

+1

いくつかのコードを投稿してください。 – JeremyP

答えて

14

通常、これはNSArrayの範囲外のインデックスにある要素にアクセスしようとすると発生します。

だから、あなたがこのようなNSArrayを持っていたと言う:

NSArray *a = [NSArray arrayWithObjects:@"a", @"b", @"c", nil]; 

境界が0であるため、このコードは、「範囲外の配列のインデックス」を印刷します - 2:

@try { 
    NSString *string = [a objectAtIndex:3]; 
} @catch(NSRangeException *e) { 
    NSLog(@"Array index out of bounds"); 
} 

解決するための最良の方法この問題は、高速列挙を使用することです。

​​3210

高速列挙では、列挙可能オブジェクトのNSFastEnumerationプロトコルの実装を使用して、すべての汚い作業を処理します。 などの可変構造を列挙し、ループの本体の内部にremoveObject:またはその変形を使用して構造を変更すると、通常は高速列挙を使用していてもこの問題が発生することが1つあります。構造体の長さがキャッシュされているため、遅くてもすぐにこの例外が実行されるため、境界外になっても次の繰り返しに進むことになります。

しかし、内部__NSFastEnumerationMutationHandlerはそれをキャッチし、次の例外をスローしますので、高速列挙体を使用して、あなたはかなり早く、このエラーをキャッチします:

2011-02-11 00:30:49.825 MutableNSFastEnumerationTest[10547:a0f] *** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <NSCFArray: 0x10010c960> was mutated while being enumerated.<CFArray 0x10010c960 [0x7fff70c45ee0]>{type = mutable-small, count = 2, values = (
    0 : <CFString 0x100001078 [0x7fff70c45ee0]>{contents = "b"} 
    1 : <CFString 0x100001058 [0x7fff70c45ee0]>{contents = "c"} 
)}' 
*** Call stack at first throw: 
(
    0 CoreFoundation      0x00007fff8621e7b4 __exceptionPreprocess + 180 
    1 libobjc.A.dylib      0x00007fff80daa0f3 objc_exception_throw + 45 
    2 CoreFoundation      0x00007fff862765bf __NSFastEnumerationMutationHandler + 303 
    3 MutableNSFastEnumerationTest  0x0000000100000de7 main + 295 
    4 MutableNSFastEnumerationTest  0x0000000100000cb8 start + 52 
    5 ???         0x0000000000000001 0x0 + 1 
) 
terminate called after throwing an instance of 'NSException' 
+1

実際には、オブジェクトを削除する最後の例は、 'i'をインクリメントしているだけでなく配列を左にシフトしているため、インデックスをスキップします。だからあなたはインデックス0、次に2、そして4などを削除するだろう。 – Tim

+0

@TimGostonyうわー、うまくキャッチ!むしろ不要な例を削除しました。ありがとう! –

+0

また、インデックスを使用せずに配列を列挙したり変更したりするうまい方法は、次のようなものです: 'for(Object * something in [myMutableArr copy]){/ * ... */[myMutableArr removeObject:something]; } ' – Tim

1

あなたの例外はあなたが出て、何かにアクセスしようとしていることを示唆されましたあなたの配列(範囲を超えてインデックス2)の範囲の。配列にアクセスする必要がある場合は、(ループごとに)高速列挙を使用することをお勧めします。

for (NSString *str in array) 
    NSLog(@"%@", str); 

このようなことは、インデックスからの範囲外の例外を防ぎます。

1

例外のタイプは、インデックスの範囲外の例外と呼ばれます。これは通常、存在しない配列の要素にアクセスしようとするときに発生します。

関連する問題