I know NSDictionaries
as something where you need a key
in order to get a value
. But how can I iterate over all keys
and values
in a NSDictionary
, so that I know what keys there are, and what values there are? I know there is something called a for-in-loop in JavaScript
. Is there something similar in Objective-C
?

- 6,014
- 5
- 44
- 74
-
Thank for this post. If iterating in `Swift` syntax, refer this post: https://stackoverflow.com/a/24111700/419348 – AechoLiu Jul 20 '18 at 05:13
-
You may explore my humble research of dictionary iterating technics: https://stackoverflow.com/questions/71626497/obj-c-extracting-all-values-from-nsdictionary-without-copying – BorisV Apr 06 '22 at 09:08
3 Answers
Yes, NSDictionary
supports fast enumeration. With Objective-C 2.0, you can do this:
// To print out all key-value pairs in the NSDictionary myDict
for(id key in myDict)
NSLog(@"key=%@ value=%@", key, [myDict objectForKey:key]);
The alternate method (which you have to use if you're targeting Mac OS X pre-10.5, but you can still use on 10.5 and iPhone) is to use an 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]);

- 44,553
- 16
- 113
- 131

- 390,455
- 97
- 512
- 589
-
2
-
@Darthenius due to recent optimizations, fast enumeration is again faster than block-based, at least in certain cases. But if the problem you are solving allows you to use the concurrent option, the block-based approach may be faster. – Zev Eisenberg May 12 '14 at 20:41
-
-
Oops, I clicked your link, above, to open in a new tab, and didn’t even notice who wrote it or that it was on this same page. If you can still edit the above comment, you might want to, so that lazy readers don’t get the wrong idea. – Zev Eisenberg May 12 '14 at 20:48
The block approach avoids running the lookup algorithm for every key:
[dict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL* stop) {
NSLog(@"%@ => %@", key, value);
}];
Even though NSDictionary
is implemented as a hashtable (which means that the cost of looking up an element is O(1)
), lookups still slow down your iteration by a constant factor.
My measurements show that for a dictionary d
of numbers ...
NSMutableDictionary* dict = [NSMutableDictionary dictionary];
for (int i = 0; i < 5000000; ++i) {
NSNumber* value = @(i);
dict[value.stringValue] = value;
}
... summing up the numbers with the block approach ...
__block int sum = 0;
[dict enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSNumber* value, BOOL* stop) {
sum += value.intValue;
}];
... rather than the loop approach ...
int sum = 0;
for (NSString* key in dict)
sum += [dict[key] intValue];
... is about 40% faster.
EDIT: The new SDK (6.1+) appears to optimise loop iteration, so the loop approach is now about 20% faster than the block approach, at least for the simple case above.

- 6,781
- 6
- 41
- 53
This is iteration using block approach:
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.
}];
With autocompletion is very fast to set, and you do not have to worry about writing iteration envelope.

- 22,224
- 10
- 78
- 108

- 9,493
- 4
- 53
- 47
-
Thanks.. Good solution if you need mutate the `NSMutableDictionary` in the process – jose920405 May 11 '16 at 14:15