5

次のようなコード ブロックがあります。

for (NSDictionary *tmp in aCollection) {
   if ([[bar valueForKey:@"id"] isEqualToString:[tmp valueForKey:@"id"]])
   {
      break;
   }
   else
   {
      [aCollection addObject:bar];
       }
 }

これは技術的に Objective-C 2.0 の例外ですか? 高速列挙でコレクションを変更できないようです。これはエラーの結果です:

*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <NSCFArray: 0x396000> was mutated while being enumerated.'

これを解決する最善の方法は何ですか?

4

7 に答える 7

12

それを解決する方法は、列挙中に配列を変更しないことです(たとえば、オブジェクトを追加します):)

ここでの問題は、要素を追加/削除して配列を変更すると、列挙値が無効になる可能性があるため、なぜ問題になるのかということです。

あなたの場合 これを解決する最も簡単な方法は、コードのバグを修正することです。あなたのコードは、配列内のすべての項目に対して「else add」句を実行していますが、それはあなたが望むものではないと確信しています。

これを試して;

bool found = false;
for (NSDictionary *tmp in aCollection)
{
   if ([[bar valueForKey:@"id"] isEqualToString:[tmp valueForKey:@"id"]])
   {
      found = true;
      break;
   }
}

if (!found)
{
 [aCollection addObject:bar];
}
于 2009-02-16T20:34:12.167 に答える
6

コレクションのコピーを作成し、それを繰り返します。その後、問題なく交換したり、元のコレクションに追加したりできます。

于 2009-02-16T20:33:53.790 に答える
6

この線

[aCollection addObject:bar]

あなたの問題です。aCollection列挙中は変更できません。より良いアプローチは、一時的な を作成し、それNSMutableArrayに追加してから、一時的な配列でbar呼び出すことです。[aCollection addObjectsFromArray:]

例えば:

NSMutableArray *foundObjects = [NSMutableArray array];
for (NSDictionary *aDictionary in aCollection) {
    if ([[bar objectForKey:@"id"] isEqual:[aDictionary objectForKey:@"id"]])
       break;

    [foundObjects addObject:bar];
}
[aCollection addObjectsFromArray:foundObjects];
于 2009-02-16T20:34:37.687 に答える
3

The Objective-C 2.0 Programming Languageから、列挙されているコレクションを変更することはできません。

列挙は「安全」です。列挙中にコレクションを変更しようとすると、例外が発生するように、列挙子にはミューテーション ガードがあります。

于 2009-02-16T20:33:28.627 に答える
2

配列をコピーするだけです。そうしないと、反復しているコレクションをいじっています。

for (NSDictionary *tmp in aCollection.copy) {
  if ([[bar valueForKey:@"id"] isEqualToString:[tmp valueForKey:@"id"]])
     break;
  [aCollection addObject:bar];
}
于 2010-11-19T23:57:11.260 に答える
1

他の誰もが有用な回答を提供しており、それらはすべて正しいようです。

ただし、あなたのコードは、彼らが思っていることを実行しません。それはおそらくあなたが思っていることもしないでしょう。

列挙子によって返された最初のオブジェクトが bar と一致しない場合、コレクションに「bar」を追加しようとします。

バーがコレクションにまったく存在しない場合、バーを追加しようとしていると誰もが考えます。

あなたは Python の構造を取り、それを間違って移植したのではないかと思います。

于 2012-01-27T04:21:28.337 に答える
0

解決した

私はcoredataオブジェクトの列挙で同じ問題を抱えています。

ループが実行されている ARRAY に依存するサブオブジェクトを変更しないでください

同様に、ループ中にオブジェクトを変更/変更すると、このエラーが発生します

 for (LoadList *objLL in ArrLoadList) {             // here Enumaration is Going on
        // here i has removed objects in ArrLoadList and reassign the ArrLoadList .. 
        // it will gives me this error 
        // So Don't change the Main Array object 
 }
于 2012-02-25T13:56:55.570 に答える