2010-08-06 12 views
7

Sto ottenendo che la raccolta sia stata modificata mentre l'eccezione enumerata quando sto usando questo codice può suggerirmi come uscire da questa.Ottenere un'eccezione come "La raccolta è stata modificata mentre veniva enumerata"

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

Spero di ottenere una risposta rapida dal vostro lato. Grazie in anticipo, Monish.

risposta

16

Non è possibile cambiare array mentre lo si enumera. Per risolvere il problema si dovrebbe accumulare nuovi oggetti in array temporaneo e aggiungerli dopo l'enumerazione:

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. non dimenticare di rilasciare l'oggetto pTerm1 che hai creato - il tuo codice contiene perdita di memoria

In risposta al commento del poster (e all'attività effettiva) - Penso che il modo più semplice per fare il bool flag indicando se il valore del giorno è stato trovato nel ciclo. In caso contrario - aggiungere nuovo oggetto dopo ciclo si conclude:

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

Grazie per la vostra code.but utile ho avuto ancora una problem.Actually la cosa è che ho bisogno di controllare la stringa la matrice, se non è presentare devo aggiungere che alla matrice list.Now il problema è Ho avuto 3 elementi nella mia lista che non è uguale alla stringa che sto cercando, quindi è stato aggiungere l'oggetto 3 volte invece di 1 volta. Ci sono altri suggerimenti per questo. –

+0

Non è necessario rilasciare tempArray qui perché non ne siete mai diventati proprietari. Inoltre, '! (Range.location! = NSNotFound)' è uguale a '(range.location == NSNotFound)'. – JeremyP

+0

@vodkhang, non è così, basta aggiungere un nuovo elemento se uno qualsiasi degli oggetti in termsArray ha una proprietà day diversa da Str – Vladimir

2

Questa riga [termsArray addObject:pTerm1]; genererà tale eccezione. NON E 'POSSIBILE aggiungere/eliminare un elemento da una matrice all'interno di a per ogni ciclo. for (currentElement in termsArray)

0

si sta aggiungendo un oggetto alla raccolta mentre si esegue il ciclo su di esso, questo è quello che causa l'errore. la sua dichiarazione if è annidato all'interno del for

0

L'errore si verifica perché si sta aggiungendo nuovi oggetti per termsArray all'interno del ciclo for

  • Creare un nuovo array vuoto (egnewTermsArray)
  • Nel primo ciclo di creare e aggiungere questi nuovi elementi per newTermsArray
  • Allora si avrà bisogno di un secondo ciclo per aggiungere gli elementi da newTermsArray indietro nel termsArray originale
1

Sì ... non possiamo elencare mentre la serie è sempre aggiornato ... Questo potrebbe essere irritante per i programmatori che sono da ActionScript background.Some volte le cose vanno peggio del tipo "Non si ottiene nemmeno un arresto anomalo o intimazione in fase di esecuzione quando si aggiorna un conteggio di array mentre viene enumerato". L'esecuzione si comporta solo in modo anomalo in quel momento.

Si può andare per questo tipo di implementazione in cui è possibile avere piccole modifiche al codice.

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

di partecipazione al corso, questo (i < termsArray.count) potrebbe sembrare male come stiamo calcolando il conteggio per ogni iterazione ... E questo è il trucco per avere changes.But minore consiglio vivamente di VLADIMIR l'implementazione è chiara per la lettura.

-2

uso try e catch per la gestione delle eccezioni in ordine di nsmutable

@try { 
    //code for accessing element. 

    } 
    @catch (NSException *exception) { 


     /// show exception here 

    } 
+1

Questo non risponde alla domanda dell'OP. Per favore rileggi la domanda e considera la risposta di @ Vladimir. –

0

appena affrontato lo stesso problema in un'applicazione piuttosto complessa. La soluzione è semplice: crea una copia e lavora con la copia dell'array (e rimuovilo dall'originale se lo desideri) quindi elimina 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]; 
} 
Problemi correlati