2010-08-06 4 views
7

Estoy obteniendo la colección se mutó mientras se enumeraba una excepción cuando uso este código ¿alguien me puede sugerir cómo salir de esto?Obteniendo una excepción como "La colección se mutó mientras se estaba enumerando"

PaymentTerms * currentElement; 
for (currentElement in termsArray) 
{ 
    printf("\n currentElement Value........%s",[currentElement.days UTF8String]); 
    printf("\n Str value...%s",[Str UTF8String]); 
    NSRange range = [currentElement.days rangeOfString:Str options:NSCaseInsensitiveSearch]; 
    if(!(range.location != NSNotFound)) 
    { 
     PaymentTerms *pTerm1 = [[PaymentTerms alloc]init]; 
     pTerm1.days = Str; 
     printf("\n pTerm1.days...%s",[ pTerm1.days UTF8String]); 
     [termsArray addObject:pTerm1]; 
    } 
} 

Espero recibir una respuesta rápida de tu lado. Gracias de antemano, Monish.

Respuesta

16

No puede cambiar la matriz mientras la está enumerando. Como solución, debe acumular nuevos objetos en una matriz temporal y agregarlos después de la enumeración:

PaymentTerms * currentElement; 
NSMutableArray* tempArray = [NSMutableArray array]; 
for (currentElement in termsArray) 
{ 
    NSRange range = [currentElement.days rangeOfString:Str options:NSCaseInsensitiveSearch]; 
    if(!(range.location != NSNotFound)) 
    { 
     PaymentTerms *pTerm1 = [[PaymentTerms alloc]init]; 
     pTerm1.days = Str; 
     [tempArray addObject:pTerm1]; 
     [pTerm1 release]; 
    } 
} 
[termsArray addObjectsFromArray: tempArray]; 

P.S. no se olvide de liberar el objeto pTerm1 que crea - su código contiene pérdida de memoria

Respondo el comentario del cartel (y la tarea real) - Creo que la forma más fácil de hacer bool es indicar el valor del día en el ciclo. Si no es así - añadir nuevo objeto después del ciclo termina:

PaymentTerms * currentElement; 
BOOL dayFound = NO; 
for (currentElement in termsArray) 
{ 
    NSRange range = [currentElement.days rangeOfString:Str options:NSCaseInsensitiveSearch]; 
    if(range.location != NSNotFound) 
     dayFound = YES; 
} 
if (!dayFound) 
    // Create and add new object here 
+0

Gracias por su utilidad code.but Tengo uno más problem.Actually la cosa es que necesito para comprobar la cadena de la matriz si no está presente tengo que añadir a la matriz list.Now el problema es Tenía 3 elementos en mi lista que no es igual a la cadena que estoy buscando, así que estaba agregando el objeto 3 veces en lugar de 1 vez. Hay alguna otra sugerencia para esto. –

+0

No necesita liberar tempArray aquí porque nunca se apropia de él. Además, '! (Range.location! = NSNotFound)' es lo mismo que '(range.location == NSNotFound)'. – JeremyP

+0

@ vodkhang, no lo haga, simplemente agregará un nuevo elemento si alguno de los objetos en términos Array tiene una propiedad diurna diferente a la de Str – Vladimir

2

Esta línea [termsArray addObject:pTerm1]; arrojará esa excepción. NO PUEDE agregar/eliminar un elemento de una matriz dentro de a para cada ciclo. for (currentElement in termsArray)

0

está agregando un objeto a su colección ya que está girando sobre él, eso es lo que está causando el error. su estado de if se anida en el interior del for

0

El error se produce porque va a agregar nuevos objetos a termsArray dentro del bucle for

  • Crear una nueva matriz vacía (egnewTermsArray)
  • En el primer bucle de crear y añadir estos nuevos elementos para newTermsArray
  • a continuación, se necesita un segundo bucle para agregar los elementos de newTermsArray de nuevo en el termsArray originales
1

Sí ... No podemos enumerar, mientras que la matriz se está actualizando ... Esto puede ser irritante para los programadores que son de ActionScript background.Some veces las cosas van peor aún: "Incluso no se produce un bloqueo o intimación en el tiempo de ejecución cuando se actualiza una cuenta de matriz mientras se enumera": la ejecución solo se comporta de forma anormal en ese momento.

Por cierto, puede optar por este tipo de implementación donde puede tener cambios menores en su código.

for (int i=0 ; i< termsArray.count ;i++) //counting termsArray on every iteration 
{ 
    id currentElement = [ termsArray objectAtIndex:i]; 
    ...... 
    ..... 
} 

de curso, Este (i < termsArray.count) podría parecer malo como estamos calculando el recuento de cada iteración ... Y ese es el truco para tener changes.But menor que recomendaría fuertemente Vladimir implementación como está claro para la lectura.

-2

utilización tratar de atrapar para el manejo de excepción en serie nsmutable

@try { 
    //code for accessing element. 

    } 
    @catch (NSException *exception) { 


     /// show exception here 

    } 
+1

Esto no responde la pregunta de OP. Vuelva a leer la pregunta y considere la respuesta de @Vladimir. –

0

Sólo tratado con el mismo error en una aplicación bastante compleja. La solución es simple: cree una copia y trabaje con la copia de la matriz (y elimínela del original si así lo desea. Luego, descarte la copia.

for(CharacterModelNode* node in self.allPlayers) 
{ 
    // Some operation that may mutate allPlayers (ex: player dies from poison damage and is removed from this array at some other part of an app) 

} 

//workaround in some cases - create a copy of array and run operations that can kill player on this array (it will not be mutated anywhere else in the app 

NSArray* allPlayersCopy = [self.allPlayers copy]; 

for(CharacterModelNode* node in allPlayersCopy) 
{ 
    [node.character refreshBuffs]; 
} 
Cuestiones relacionadas