2009-02-16 5 views
5

Ich habe einen Block von Code, der die folgenden ähnelt:Objective-C 2.0 und Fast Enumeration wirft Ausnahmen

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

Ist dies technisch eine Ausnahme in Objective-C 2.0? Es scheint, dass Sie eine Sammlung nicht mit schneller Aufzählung mutieren können. Dies ist das Ergebnis eines Fehlers:

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

Was ist der beste Weg, um dies zu lösen?

Antwort

3

Von The Objective-C 2.0 Programming Language Sie die Sammlung aufgezählt werden, nicht ändern können: eine Kopie der Sammlung

Enumeration is “safe”—the enumerator has a mutation guard so that if you attempt to modify the collection during enumeration, an exception is raised.

6

Stellen und durch die laufen. Dann können Sie Ihre ursprüngliche Sammlung ohne Probleme austauschen oder hinzufügen.

12

Nun, der Weg, es zu lösen, ist nicht das Array zu mutieren (zB ein Objekt hinzufügen), während es Aufzählen :)

Das Problem hierbei ist, dass das Array modifiziert durch Hinzufügen/Entfernen von Elementen könnte die Aufzählungswerte bewirken, werden ungültig, weshalb es ein Problem ist.

In Ihrem Fall Der einfachste Weg, dies zu lösen, ist das Beheben des Fehlers in Ihrem Code. Ihr Code macht die "else add" -Klausel für jedes Element im Array und ich bin mir ziemlich sicher, dass das nicht das ist, was Sie wollen.

Versuchen Sie dies;

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

if (!found) 
{ 
[aCollection addObject:bar]; 
} 
6

Die Linie

[aCollection addObject:bar] 

ist Ihr Problem. Sie können aCollection nicht ändern, während Sie es aufzählen. Der bessere Ansatz wäre, ein temporäres NSMutableArray zu erstellen, bar zu diesem hinzuzufügen und dann [aCollection addObjectsFromArray:] mit Ihrem temporären Array aufzurufen.

Zum Beispiel:

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

    [foundObjects addObject:bar]; 
} 
[aCollection addObjectsFromArray:foundObjects]; 
+7

Warum die Mühe, all das, wenn Sie einfach über '[aCollection copy] 'iterieren können? –

2

Kopieren Sie einfach das Array. Sonst machst du mit der Sammlung, die du wiederholst:

+0

Downvotes? Warum? –

1

Alle anderen haben nützliche Antworten angeboten, die alle korrekt erscheinen.

Ihr Code tut jedoch nicht, was er zu tun glaubt. Es tut wahrscheinlich auch nicht, was du denkst.

Sie versuchen, der Sammlung einen 'Balken' hinzuzufügen, wenn das erste vom Enumerator zurückgegebene Objekt nicht mit dem Balken übereinstimmt.

Jeder denkt, dass Sie versuchen, eine Leiste hinzuzufügen, wenn sie in der Sammlung überhaupt nicht vorhanden ist.

Ich vermute, Sie haben ein Python-Konstrukt genommen und es falsch portiert.

+0

Dies ist ein Kommentar, keine Frage. Du hast wahrscheinlich recht, obwohl :) –

0

gelöst

i gleiches Problem in Coredata Aufzählung Objekte.

nicht sub-Objekt ändern, die in ARRAY beruht auf dem Loop-

Wie ausgeführt wird, wenn i/ändern, während auf der Schleife Objekt geändert .. wird es diesem Fehler gibt

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 
} 
Verwandte Themen