Domanda

Lo so NSDictionaries come qualcosa in cui avete bisogno di un key al fine di ottenere un value. Ma come posso iterare su tutti keys e values in un NSDictionary, in modo che io so quello che le chiavi ci sono, e quali valori ci sono? So che c'è qualcosa che si chiama un per-in-loop in JavaScript. C'è qualcosa di simile in Objective-C?

È stato utile?

Soluzione

Sì, NSDictionary supporta l'enumerazione veloce. Con Objective-C 2.0, si può fare questo:

// To print out all key-value pairs in the NSDictionary myDict
for(id key in myDict)
    NSLog(@"key=%@ value=%@", key, [myDict objectForKey:key]);

Il metodo alternativo (che si deve utilizzare se ci si rivolge Mac OS X pre-10.5, ma è comunque possibile utilizzare il 10.5 e iPhone) è di usare un NSEnumerator:

NSEnumerator *enumerator = [myDict keyEnumerator];
id key;
// extra parens to suppress warning about using = instead of ==
while((key = [enumerator nextObject]))
    NSLog(@"key=%@ value=%@", key, [myDict objectForKey:key]);

Altri suggerimenti

L'approccio blocco consente di evitare l'esecuzione l'algoritmo di ricerca per ogni tasto :

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

Anche se NSDictionary è implementato come una tabella hash (il che significa che il costo di guardare in alto un elemento è O(1) ), le ricerche ancora rallentano la tua iterazione per un fattore costante .

I miei misurazioni mostrano che per una d dizionario dei numeri ...

NSMutableDictionary* dict = [NSMutableDictionary dictionary];
for (int i = 0; i < 5000000; ++i) {
  NSNumber* value = @(i);
  dict[value.stringValue] = value;
}

... riassumendo i numeri con l'approccio a blocchi ...

__block int sum = 0;
[dict enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSNumber* value, BOOL* stop) {
  sum += value.intValue;
}];

... piuttosto che l'approccio del ciclo ...

int sum = 0;
for (NSString* key in dict)
  sum += [dict[key] intValue];

... è di circa il 40% più veloce .

Modifica : il nuovo SDK (6.1+) appare per ottimizzare iterazione del ciclo, in modo da l'approccio ciclo è ora circa il 20% più veloce rispetto al metodo blocco , almeno per il semplice caso di cui sopra.

Questo è iterazione con approccio modulare:

    NSDictionary *dict = @{@"key1":@1, @"key2":@2, @"key3":@3};

    [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        NSLog(@"%@->%@",key,obj);
        // Set stop to YES when you wanted to break the iteration.
    }];

Con il completamento automatico è molto veloce da impostare, e non devi preoccuparti di scrivere busta iterazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top