247

Ich finde einige Schwierigkeiten beim Zugriff auf änderbare Wörterbuchschlüssel und Werte in Objective-C.für jede Schleife in Ziel c für den Zugriff auf NSMutable-Wörterbuch

Angenommen, ich habe dies:

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

I Schlüssel und Werte einstellen. Jetzt möchte ich nur auf jeden Schlüssel und Wert zugreifen, aber ich kenne die Anzahl der Schlüssel nicht.

In PHP ist es sehr einfach, etwas wie folgt:

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

Wie ist es möglich, in Objective-C?

Antwort

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

Diese für jede Klasse arbeitet, die dem NSFastEnumeration-Protokoll (auf 10.5 + und iOS verfügbar) entspricht, obwohl NSDictionary einer der wenigen Sammlungen, die Sie Schlüssel anstelle der Werte aufzählen können. Ich schlage vor, Sie lesen über fast enumeration in der Collections Programming Topic.

Oh, ich sollte jedoch hinzufügen, dass Sie sollten NIEMALS eine Sammlung während der Aufzählung durch sie ändern.

+3

Ich frage mich, sollte es nicht gewesen sein: für (NSString * Schlüssel in [xyz allKeys]) ?? Oder ist es nicht wirklich wichtig? –

+5

@ user76859403 Das Aufzählen eines Wörterbuchs listet tatsächlich die Schlüssel auf.'for (NSString * key in [xyz allKeys])' ist konzeptionell das Gleiche. – zneak

+0

Verwenden Sie [xyz allKeys], wenn Sie das Wörterbuch beim Aufzählen der Schlüssel mutieren müssen. Siehe meine Antwort unten. –

1

Sie können -[NSDictionary allKeys] verwenden, um auf alle Schlüssel zuzugreifen und sie zu durchlaufen.

+2

Das stimmt, aber das schafft ein extra automatisches Array, das ziemlich verschwenderisch sein kann, besonders für Wörterbücher mit vielen Schlüsseln. –

2

Schnelle Aufzählung wurde in 10.5 und im iPhone OS hinzugefügt, und es ist deutlich schneller, nicht nur syntaktischer Zucker. Wenn Sie die ältere Laufzeit (dh 10,4 und rückwärts) zum Ziel haben, werden Sie die alte Methode von Aufzählen verwenden müssen:

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" ... 
} 

Sie entbinden nicht Enumeratorobjekt, und Sie können es nicht zurückgesetzt . Wenn Sie von vorn beginnen möchten, müssen Sie nach einem neuen Enumerator-Objekt aus dem Wörterbuch fragen.

94

Nur um nicht die für Aufzählen Schlüssel und Werte 10.6+ Option auslassen Blöcke mit ...

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

Wenn Sie die Aktionen gleichzeitig passieren soll:

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

3 verschiedene Möglichkeiten zum Aufzählen über ein Wörterbuch. . . heh, das erinnert mich an die "Strangeest Language Feature" Antwort wo VB 7 verschiedene Arten von Loops hat. – dreamlax

+3

Well ... objectEnumerator wurde 1994 hinzugefügt, die für (... in ...) in etwa 2006, und Blöcke wurden 2009 hinzugefügt. Die Blockform der Aufzählung ist natürlich Fallout. – bbum

+0

Dies scheint schneller zu sein als der Standard * für ... in * Konstrukt: http://oneofthesedaysblog.com/block-vs-for-in-objective-c-enumeration – lkraider

10

Wenn Sie müssen das Wörterbuch mutieren, während aufzählt:

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

Der Grund ist 'allKeys' gibt eine Kopie der Schlüssel zurück. So ist es sicher, das Wörterbuch zu mutieren. –

3

Der einfachste Weg, ein Wörterbuch aufzuzählen ist

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

wo tDictionary ist die NSDictionary oder NSMutableDictionary Sie iterieren möchten.