für jede Schleife in Objective-C für den Zugriff auf das NSMutable-Wörterbuch


268

Ich habe einige Schwierigkeiten beim Zugriff auf veränderbare Wörterbuchschlüssel und -werte in Objective-C.

Angenommen, ich habe Folgendes:

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

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

In PHP ist es sehr einfach, etwas wie folgt:

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

Wie ist es in Objective-C möglich?

Antworten:


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

Dies funktioniert für jede Klasse, die dem NSFastEnumeration-Protokoll (verfügbar ab 10.5 und iOS) entspricht, NSDictionaryist jedoch eine der wenigen Sammlungen, mit denen Sie Schlüssel anstelle von Werten auflisten können. Ich schlage vor, Sie lesen etwas über die schnelle Aufzählung im Thema Programmierung von Sammlungen .

Oh, ich sollte jedoch hinzufügen, dass Sie NIEMALS eine Sammlung ändern sollten, während Sie sie aufzählen.


4
Ich habe mich gefragt, hätte es nicht sein sollen: für (NSString * tippe [xyz allKeys] ein) ?? Oder spielt es keine Rolle?
FlowUI. SimpleUITesting.com

6
@ user76859403 Beim Auflisten eines Wörterbuchs werden die Schlüssel aufgelistet. for (NSString* key in [xyz allKeys])ist konzeptionell das gleiche.
Zneak

Verwenden Sie [xyz allKeys], wenn Sie das Wörterbuch während der Aufzählung der Schlüssel mutieren müssen. Siehe meine Antwort unten.
Brody Robertson

Gibt diese Schleife immer die gleiche Reihenfolge zurück? Oder brauchen wir eine andere Möglichkeit, es für TableView-Abschnitte zu verwenden?
Ymutlu

1
@ymutlu, Kakaowörterbücher sind ungeordnet. Dies bedeutet, dass sich die Reihenfolge, in der sie iterieren, ändern kann, wenn Sie sie ändern.
Zneak

98

Nur um die Option 10.6+ zum Aufzählen von Schlüsseln und Werten mithilfe von Blöcken nicht auszulassen ...

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

Wenn Sie möchten, dass die Aktionen gleichzeitig ausgeführt werden:

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

2
3 verschiedene Möglichkeiten, ein Wörterbuch aufzulisten. . . heh, das erinnert mich an die Antwort "Strangest Language Feature", bei der VB 7 verschiedene Arten von Schleifen hat.
Dreamlax

3
Nun ... objectEnumerator wurde 1994 hinzugefügt, der for (... in ...) ungefähr 2006 und Blocks wurden 2009 hinzugefügt. Die Blockform der Aufzählung ist ein natürlicher Fallout.
bbum

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

1
@lkraider, ich habe diesen Beitrag kommentiert, der die blockbasierte Aufzählung tatsächlich mit einer alten for-Schleife vergleicht, nicht mit der for ... im Konstrukt.
Quinn Taylor

Wofür ist das *stop? Wie nutzt du es? Irgendeine Referenz?
Borisdiakur

13

Wenn Sie das Wörterbuch während der Aufzählung mutieren müssen :

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

Der Grund ist, dass allKeyseine Kopie der Schlüssel zurückgegeben wird. Es ist also sicher, das Wörterbuch zu mutieren.
Honghao Zhang

5

Der einfachste Weg, ein Wörterbuch aufzulisten, ist

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

wo tDictionaryist das NSDictionaryoder NSMutableDictionarydu willst iterieren.



2

In 10.5 und im iPhone OS wurde eine schnelle Aufzählung hinzugefügt, die nicht nur syntaktischen Zucker, sondern auch erheblich schneller ist. Wenn Sie auf die ältere Laufzeit (z. B. 10.4 und zurück) abzielen müssen, müssen Sie die alte Aufzählungsmethode verwenden:

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 geben das Enumerator-Objekt nicht frei und können es nicht zurücksetzen. Wenn Sie von vorne beginnen möchten, müssen Sie ein neues Enumerator-Objekt aus dem Wörterbuch anfordern.


1

Sie können -[NSDictionary allKeys]damit auf alle Schlüssel zugreifen und diese durchlaufen.


2
Stimmt, aber dies erzeugt ein zusätzliches autorelease-Array, was ziemlich verschwenderisch sein kann, insbesondere für Wörterbücher mit vielen Schlüsseln.
Quinn Taylor
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.