2010-05-03 18 views
15

imbattermi nel seguente scorciatoia nella creazione di un ciclo (scorciatoia rispetto agli esempi da manuale ho utilizzato):Rimozione oggetto da NSMutableArray

for (Item *i in items){ ... } 

in contrasto con il formato più:

for (NSInteger i = 0; i < [items count]; i++){ ... } //think that's right 

Se sto usando la versione più breve, c'è un modo per rimuovere l'elemento attualmente sottoposto a iterazione (cioè 'i')? O devo usare il formato più lungo?

+0

Il primo ciclo for è conosciuto come il maggiore ciclo FOR, e la seconda uno è il vecchio ciclo FOR standard. Lo imparo quando faccio la mia certificazione Java. – Popeye

+0

Se è davvero necessario rimuovere gli elementi dall'array mentre lo si itera e non è possibile rimuoverli in seguito utilizzando 'removeObjectsInArray:' o 'removeObjectsAtIndexes:' come suggerito da @Vladimir, è sempre possibile eseguire l'iterazione su una copia dell'array originale. – Tiago

risposta

31

Non si può rimuovere gli oggetti dalla serie, mentre fast-enumerating esso:

numerazione è “sicuro” -la enumeratore ha una guardia mutazione in modo che se si tentativo di modificare la raccolta durante l'enumerazione, un'eccezione è sollevato.

In ogni caso, perché è necessario cambiare contenitore mentre lo si enumera? Prendi in considerazione la possibilità di memorizzare elementi che devono essere eliminati e rimuoverli dal tuo contenitore usando il metodo removeObjectsInArray: o removeObjectsAtIndexes:.

+0

Grazie. Lo sto cambiando mentre lo enumeriamo perché è una coda temporanea. Sto spostando tutti gli elementi in un altro array. –

+1

Se si spostano * tutti * gli oggetti su un altro array, provare quanto segue: '[destinationArray addObjectsFromArray: sourceArray]; [sourceArray removeAllObjects]; ' – JeremyP

+0

Sì, l'ho trovato - grazie. –

1

Il primo ciclo è un "per-ogni" loop in Objective C.

* i è un puntatore all'elemento diretto nella Articoli-Array (il più delle volte questo sarà NSMutableArray).

questo modo è possibile operare direttamente sul prodotto:

[items removeObject: i]; 

Questo (dovrebbe) lavoro - io non sto lavorando sul mio Mac e non riesco a controllare. Tuttavia potrebbe essere che Objective-C impedisca la rimozione di oggetti durante l'iterazione sulla raccolta (che è abbastanza comune nella maggior parte delle lingue).

+0

In effetti, non è possibile rimuovere (o modificare) un 'NSMutableArray' mentre si esegue l'enumerazione su di esso, quindi la chiamata' removeObject: 'genererà un'eccezione. (come spiegato da Vladimir nella sua risposta) –

9

Basta aggiungere parole chiave break; dopo aver rimosso la voce ...

for(id item in items) { 
    if([item isEqual:itemToDelete]) { 
     [items removeObject:item]; 
     break; 
    } 
} 
+4

@ Abdullah71 con id non si usa mai *. – rptwsthi

+0

Questo rimuoverà un oggetto e interromperà l'iterazione, perdendo così possibili altri oggetti che dovrebbero essere rimossi. Quindi usalo solo se hai bisogno di rimuovere zero su un oggetto per iterazione. – marsbear

3

Una collezione Objective-C non deve essere modificato durante l'enumerazione.

È possibile utilizzare questa variante per eliminare gli oggetti da collezione:

for (NSInteger i = items.count - 1; i >= 0 ; i--) { 
    [items removeObjectAtIndex:i]; 
} 
+0

Imho il modo più breve per farlo correttamente, dato che va bene con la tua logica di business per attraversare la matrice dal retro al fronte. – marsbear

0

Io uso questo codice per questo:

for (NSUInteger i = [items count] - 1; ; i--) { 
    [items removeObjectAtIndex:i]; 
} 
+0

Ciclo infinito ?! – Pang

+0

Solo fino a quando ottengo -1 ... poi si blocca :) – marsbear