2009-02-16 21 views
5

que tienen un bloque de código que es similar al siguiente:enumeración lanzar excepciones Objective-C 2.0 y Fast

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?

Respuesta

3

De The Objective-C 2.0 Programming Language, no se puede modificar la colección empadronado:

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

hacer una copia de la recogida y iterar a través de eso. Luego puede cambiar o agregar a su colección original sin problemas.

12

Bueno, la forma de resolverlo no es mutar la matriz (por ejemplo, añadir un objeto) al enumerar él :)

El problema aquí es que la modificación de la matriz mediante la adición/eliminación de elementos podría causar que los valores de la enumeración de convertirse en inválido, por lo tanto, ¿por qué es un problema.

En su caso La forma más fácil de resolver esto es solucionar 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.

Pruebe 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]; 
} 
6

La línea

[aCollection addObject:bar] 

es su problema. No puede modificar aCollection al enumerarlo. El mejor enfoque sería crear un NSMutableArray temporal, agregar bar a eso, luego llamar al [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]; 
+7

Por qué se molestó en hacer todo esto cuando puedes iterar sobre '[una copia de colección]'? –

2

sólo copiar la matriz. De lo contrario te estás metiendo en la colección que está iterando:

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

Votos descendentes? ¿Por qué? –

1

Todos los demás han ofrecido respuestas útiles, todos los cuales parecen correctos.

Su código, sin embargo, 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.

Todo el mundo piensa que está 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.

+0

Este es un comentario, no una pregunta. Probablemente tienes razón, sin embargo :) –

0

resuelto

i tiene el mismo problema en coredata objetos enumeración.

no cambian subobjeto que se basa en la matriz en la que se está ejecutando en bucle

Al igual que, si cambiaba/modificar objeto, mientras que 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 
} 
Cuestiones relacionadas