per ogni ciclo in Objective-C per l'accesso al dizionario NSMutable


268

Sto riscontrando difficoltà nell'accedere a chiavi e valori di dizionario mutabili in Objective-C.

Supponiamo di avere questo:

NSMutableDictionary *xyz=[[NSMutableDictionary alloc] init];

Posso impostare chiavi e valori. Ora voglio solo accedere a ogni chiave e valore, ma non conosco il numero di chiavi impostate.

In PHP è molto semplice, qualcosa come segue:

foreach ($xyz as $key => $value)

Come è possibile in Objective-C?

Risposte:


662
for (NSString* key in xyz) {
    id value = xyz[key];
    // do stuff
}

Questo funziona per ogni classe conforme al protocollo NSFastEnumeration (disponibile su 10.5+ e iOS), sebbene NSDictionarysia una delle poche raccolte che ti consente di enumerare le chiavi anziché i valori. Ti suggerisco di leggere l' enumerazione rapida nell'argomento di programmazione delle raccolte .

Oh, dovrei aggiungere comunque che non dovresti MAI modificare una raccolta mentre la enumeri attraverso di essa.


4
Mi chiedevo, non avrebbe dovuto essere: for (NSString * key in [xyz allKeys]) ?? O non importa davvero.
FlowUI. SimpleUITesting.com

6
@ user76859403 L'enumerazione di un dizionario, infatti, enumera le chiavi. for (NSString* key in [xyz allKeys])è concettualmente la stessa cosa.
zneak,

Utilizzare [xyz allKeys] se è necessario mutare il dizionario durante l'enumerazione delle chiavi. Vedi la mia risposta qui sotto.
Brody Robertson,

Questo loop restituisce sempre lo stesso ordine? O abbiamo bisogno di un altro modo per usarlo per le sezioni TableView?
ymutlu,

1
@ymutlu, i dizionari di cacao non sono ordinati. Ciò significa che l'ordine in cui ripetono può cambiare ogni volta che li modifichi.
zneak,

98

Solo per non tralasciare l'opzione 10.6+ per enumerare chiavi e valori usando i blocchi ...

[dict enumerateKeysAndObjectsUsingBlock:^(id key, id object, BOOL *stop) {
    NSLog(@"%@ = %@", key, object);
}];

Se si desidera che le azioni si verifichino contemporaneamente:

[dict enumerateKeysAndObjectsWithOptions:NSEnumerationConcurrent
                              usingBlock:^(id key, id object, BOOL *stop) {
    NSLog(@"%@ = %@", key, object);
}];

2
3 modi diversi per enumerare un dizionario. . . eh, questo mi ricorda la risposta "Strangest Language Feature" in cui VB ha 7 diversi tipi di loop.
dreamlax,

3
Bene ... objectEnumerator è stato aggiunto nel 1994, il for (... in ...) nel 2006 circa, e Blocks sono stati aggiunti nel 2009. La forma a blocchi dell'enumerazione è fallout naturale.
bbum

Questo sembra essere più veloce dello standard per ... in costruzione: oneofthesedaysblog.com/block-vs-for-in-objective-c-enumeration
lkraider

1
@lkraider, ho commentato quel post, che in realtà confronta l'enumerazione basata su blocchi con un vecchio ciclo for, non il for ... nel costrutto.
Quinn Taylor,

A cosa serve *stop? Come lo usi? Qualche riferimento?
borisdiakur,

13

Se è necessario mutare il dizionario durante l'enumerazione:

for (NSString* key in xyz.allKeys) {
    [xyz setValue:[NSNumber numberWithBool:YES] forKey:key];
}

Il motivo è che allKeysrestituisce una copia delle chiavi. Quindi è sicuro mutare il dizionario.
Honghao Zhang,

5

Il modo più semplice per enumerare un dizionario è

for (NSString *key in tDictionary.keyEnumerator) 
{
    //do something here;
}

dove tDictionaryè il NSDictionaryo NSMutableDictionaryche si desidera iterare.



2

L'enumerazione rapida è stata aggiunta in 10.5 e nel sistema operativo iPhone, ed è significativamente più veloce, non solo zucchero sintattico. Se devi scegliere come target il runtime precedente (ovvero 10.4 e versioni precedenti), dovrai utilizzare il vecchio metodo di enumerazione:

NSDictionary *myDict = ... some keys and values ...
NSEnumerator *keyEnum = [myDict keyEnumerator];
id key;

while ((key = [keyEnum nextObject]))
{
    id value = [myDict objectForKey:key];
    ... do work with "value" ...
}

Non si rilascia l'oggetto enumeratore e non è possibile ripristinarlo. Se si desidera ricominciare, è necessario richiedere un nuovo oggetto enumeratore dal dizionario.


1

È possibile utilizzare -[NSDictionary allKeys]per accedere a tutti i tasti e scorrere in esso.


2
È vero, ma questo crea un array con rilascio automatico aggiuntivo, che può essere piuttosto dispendioso, soprattutto per i dizionari con molte chiavi.
Quinn Taylor,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.