By Sagar R. Kothari

2010-01-26 23:03:28 8 Comments

I am finding some difficulty in accessing mutable dictionary keys and values in Objective-C.

Suppose I have this:

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

I can set keys and values. Now, I just want to access each key and value, but I don't know the number of keys set.

In PHP it is very easy, something as follows:

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

How is it possible in Objective-C?


@zneak 2010-01-26 23:06:01

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

This works for every class that conforms to the NSFastEnumeration protocol (available on 10.5+ and iOS), though NSDictionary is one of the few collections which lets you enumerate keys instead of values. I suggest you read about fast enumeration in the Collections Programming Topic.

Oh, I should add however that you should NEVER modify a collection while enumerating through it.

@iOS Calendar 2012-04-02 04:23:24

I was wondering, should'nt it have been: for (NSString* key in [xyz allKeys]) ?? Or does it not really matter.

@zneak 2012-04-02 05:09:27

@user76859403 Enumerating a dictionary, in fact, enumerates the keys. for (NSString* key in [xyz allKeys]) is conceptually the same thing.

@Brody Robertson 2013-06-03 20:05:46

Use [xyz allKeys] if you need to mutate the dictionary while enumerating the keys. See my answer below.

@ymutlu 2014-10-31 14:55:30

Is this loop return same order all the time? Or do we need another way to use it for TableView sections?

@zneak 2014-10-31 17:43:00

@ymutlu, Cocoa dictionaries are unordered. This means that the order in which they iterate may change whenever you modify them.

@Laurent Etiemble 2010-01-26 23:05:54

I suggest you to read the Enumeration: Traversing a Collection’s Elements part of the Collections Programming Guide for Cocoa. There is a sample code for your need.

@Quinn Taylor 2010-01-26 23:41:53

Those are good links, although the code @zneak posted is much simpler and faster, if you can build for 10.5+ or iPhone.

@Avinash 2013-12-17 10:17:01

The easiest way to enumerate a dictionary is

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

where tDictionary is the NSDictionary or NSMutableDictionary you want to iterate.

@Brody Robertson 2013-06-03 20:10:00

If you need to mutate the dictionary while enumerating:

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

@Honghao Zhang 2018-03-10 04:05:50

The reason is allKeys returns a copy of keys. So it's safe to mutate the dictionary.

@gcamp 2010-01-26 23:07:57

You can use -[NSDictionary allKeys] to access all the keys and loop through it.

@Quinn Taylor 2010-01-27 06:11:17

True, but this does create an extra autoreleased array, which can be quite wasteful, especially for dictionaries with lots of keys.

@dreamlax 2010-01-27 00:40:27

Fast enumeration was added in 10.5 and in the iPhone OS, and it's significantly faster, not just syntactic sugar. If you have to target the older runtime (i.e. 10.4 and backwards), you'll have to use the old method of enumerating:

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

You don't release the enumerator object, and you can't reset it. If you want to start over, you have to ask for a new enumerator object from the dictionary.

@Quinn Taylor 2010-01-27 05:43:35

Just to not leave out the 10.6+ option for enumerating keys and values using blocks...

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

If you want the actions to happen concurrently:

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

@dreamlax 2010-01-27 05:47:29

3 different ways to enumerate through a dictionary . . . heh, this reminds me of the "Strangest Language Feature" answer where VB has 7 different kinds of loops.

@bbum 2010-02-08 04:25:14

Well... objectEnumerator was added in 1994, the for(... in ...) in about 2006, and Blocks were added in 2009. The block form of enumeration is natural fallout.

@lkraider 2011-07-08 20:40:47

This seems to be faster than the standard construct:‌​on

@Quinn Taylor 2011-08-09 00:27:17

@lkraider, I commented on that post, which actually compares block-based enumeration with an old for loop, not the construct.

@borisdiakur 2012-09-04 20:27:57

What is the *stop for? How do you make use of it? Any reference?

@Parag Bafna 2012-10-12 09:05:49

Set *stop = YES;to stop any further enumeration inside the block

@mkko 2014-01-26 17:14:24

Also, due to the nature of Objective C and its missing ability for method overloading, you can give types for the key and object. For example: ... enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, UIImage *img, BOOL *stop) { ....

Related Questions

Sponsored Content

26 Answered Questions

[SOLVED] How do I sort an NSMutableArray with custom objects in it?

15 Answered Questions

[SOLVED] Swift for loop: for index, element in array?

29 Answered Questions

[SOLVED] Shortcuts in Objective-C to concatenate NSStrings

13 Answered Questions

[SOLVED] What is a typedef enum in Objective-C?

15 Answered Questions

[SOLVED] C# loop - break vs. continue

  • 2008-08-08 21:49:01
  • Seibar
  • 731583 View
  • 785 Score
  • 15 Answer
  • Tags:   c# loops enumeration

2 Answered Questions

[SOLVED] NSDictionary - Need to check whether dictionary contains key-value pair or not

1 Answered Questions

[SOLVED] Access object of Nested NSDictionary

2 Answered Questions

[SOLVED] Strange behavior reading Dictionary from a plist file

Sponsored Content