objective-c cocoa cocoa-touch enumeration

objective c - Objective-C 2.0 y Fast Enumeration throwing exceptions



cocoa cocoa-touch (7)

Tengo un bloque de código que es similar al siguiente:

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

¿Es esto técnicamente una excepción en Objective-C 2.0? Parece que no se puede mutar una colección con enumeración rápida. Este es el resultado de un error:

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

¿Cuál es la mejor manera de resolver esto?


Bueno, la forma de resolverlo no es mutar la matriz (por ejemplo, agregar un objeto) al enumerarlo :)

El problema aquí es que modificar la matriz mediante la adición / eliminación de elementos podría hacer que los valores de la enumeración no sean válidos, por lo que es un problema.

En su caso La forma más fácil de resolver esto es arreglar el error en su código. Su código está haciendo la cláusula "else add" para cada elemento de la matriz y estoy seguro de que no es lo que quiere.

Prueba esto;

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


Desde The Objective-C 2.0 Programming Language , no puede modificar la colección que se enumera:

La enumeración es "segura": el enumerador tiene un protector de mutación, de modo que si intenta modificar la recopilación durante la enumeración, se genera una excepción.


Haga una copia de la colección y repita eso. Luego puede cambiar o agregar a su colección original sin problemas.


La línea

[aCollection addObject:bar]

es tu problema. No puede modificar una aCollection al enumerarla. El mejor enfoque sería crear un NSMutableArray temporal, agregar una bar a eso y luego llamar a [aCollection addObjectsFromArray:] con su matriz temporal.

Por ejemplo:

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


Solo copie la matriz. De lo contrario, estás jugando con la colección que estás iterando:

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


Todos los demás han ofrecido respuestas útiles, todas las cuales parecen correctas.

Sin embargo, su código no hace lo que creen que hace. Probablemente tampoco haga lo que piensas que hace.

Intenta agregar ''barra'' a la colección si el primer objeto devuelto por el enumerador no coincide con la barra.

Todos piensan que estás intentando agregar una barra si no existe en absoluto en la colección.

Sospecho que tomó una construcción de Python y la portó incorrectamente.


resuelto

Tengo el mismo problema en la enumeración de objetos de coredata.

no cambie el objeto secundario que se basa en ARRAY en el que se está ejecutando Loop

Me gusta, si cambié / modifico el objeto mientras estaba en el bucle ... dará este error

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 }