2012-02-27 5 views
2

私は2つの反復方法にいくつか問題があります。Objective Cの2つの反復方法の違いは?

NSArray *array=[[NSArray alloc] initWithObjects:@"A",@"B",@"C",@"D",nil]; 

NSMutableArray *mutArray=[[NSMutableArray alloc] initWithArray:array]; 

私はこのように行うとき、それは正しい

for (int i=0;[mutArray count]!=0;) { 
    [mutArray removeObjectAtIndex:i]; 
} 
NSLog(@"%d,",[mutArray count]); 

を作業だが、私はこのように行うとき、それはクラッシュだ...なぜ?

for(id obj in mutArray) 
{ 
    [mutArray removeObject:obj] 
} 
NSLog(@"%d,",[mutArray count]); 

解決策を教えてください。

+0

ねえ、この投稿をチェックしてください:http://stackoverflow.com/questions/5826336/remove-items-in-a-for-loop-without-side-effects-なぜあなたは配列から項目を削除できません高速forループを使用します。 –

+0

@ joerickさんの答えはちょうど参考になりますが、FYI thisは存在します: '[mutArray removeAllObjects];';) – deanWombourne

答えて

2

第2のケースは、高速列挙と呼ばれます。高速列挙のインプリメンテーションの詳細により、配列が高速列挙されている間は配列を編集できません。

は、私はしばしば次のようにしてこの問題を回避:

for(id obj in [[mutArray copy] autorelease]) 
{ 
    [mutArray removeObject:obj] 
} 
NSLog(@"%d,",[mutArray count]); 

あなたは、配列の一時コピーの繰り返し処理をやっている。この方法ではなく、あなたを介して行くようにあなたは、元を変更することができます。

p.s.高速列挙は列挙の開始時にオブジェクトのC配列を要求することで機能しますので、高速列挙中は編集できません。取得した後は、列挙間にObjective-Cメッセージ呼び出しがないため、反復処理は高速です。ただし、配列を変更すると、C配列は内容の有効な表現ではなくなり、例外が発生します。

2

コレクションが高速列挙されている間は、そのコレクションを変更しないでください。

ファスト列挙は、コレクションから要素のグループを要求することによって機能します。これは、パフォーマンスと正確さのためにこれを行います。要素のスライスを列挙しているので、プログラムは常にコンテナへのラウンドトリップを行う必要はありません。しかし、列挙子の背後でコレクションを変更すると、正しさとオブジェクトの存続期間のすべての保証が失われます。

この場合、コンソールにエラーが表示されます。

参照:-removeAllObjects

+0

これの背後にある理由は何ですか? –

+0

@maddycoderが更新されました – justin

+1

ref:https://developer.apple.com/library/ios/#documentation/cocoa/conceptual/objectivec/Chapters/ocFastEnumeration.html – Hanon

0

私の提案:

NSMutableArray *temps = [NSMutableArray array]; 
for(id obj in mutArray) 
{ 
    // checking condition here 
    [temps addObject:obj]; 
} 
[mutArray removeObjectsInArray:temps]; 
0

コレクションを変異さは、列挙子を無効にします。列挙子は変更を検出し、エラーをトリガします。高速列挙では、削除する必要があるものをマークするか、1位でインデックスを使用することができます。

関連する問題