Objective-C
NSMutableDictionary
looping
iOS development
dictionary iteration

looping through an NSMutableDictionary

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Looping through an NSMutableDictionary is straightforward once you remember two things: iteration is usually over keys, and the dictionary is unordered. The main practical concern is not how to write the loop, but how to do it safely without mutating the dictionary during enumeration in a way that raises an exception.

Fast Enumeration Over Keys

The most common Objective-C pattern is fast enumeration.

objective-c
1NSMutableDictionary *dict = [@{
2    @"name": @"Ana",
3    @"role": @"admin",
4    @"active": @YES
5} mutableCopy];
6
7for (id key in dict) {
8    id value = dict[key];
9    NSLog(@"%@ -> %@", key, value);
10}

This loops over the keys, and you use each key to retrieve the corresponding value. It is concise and usually the clearest choice for ordinary traversal.

Iterate With enumerateKeysAndObjectsUsingBlock:

If you want both key and value directly, block-based enumeration is often more expressive.

objective-c
[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
    NSLog(@"%@ -> %@", key, obj);
}];

This style is convenient when you want to:

  • access both key and value without an extra lookup,
  • stop early with *stop = YES,
  • keep the iteration body compact.

The Dictionary Has No Guaranteed Order

A dictionary is not a sorted collection. If you loop through an NSMutableDictionary, you should not assume insertion order or alphabetical order.

If order matters, sort the keys first.

objective-c
1NSArray *sortedKeys = [[dict allKeys] sortedArrayUsingSelector:@selector(compare:)];
2for (id key in sortedKeys) {
3    NSLog(@"%@ -> %@", key, dict[key]);
4}

This is important for UI output, test reproducibility, and any logic that depends on stable ordering.

Do Not Mutate While Fast-Enumerating

One of the most common mistakes is changing the dictionary while iterating it.

objective-c
1for (id key in dict) {
2    if ([key isEqual:@"role"]) {
3        [dict removeObjectForKey:key];
4    }
5}

That can raise a mutation-during-enumeration exception.

If you need to remove entries, iterate over a snapshot of keys instead.

objective-c
1for (id key in [dict allKeys]) {
2    if ([key isEqual:@"role"]) {
3        [dict removeObjectForKey:key];
4    }
5}

Now the iteration runs over an immutable array of keys, so mutating the dictionary itself is safe.

Filtering While Iterating

A common real-world use case is scanning the dictionary and building another result.

objective-c
1NSMutableDictionary *filtered = [NSMutableDictionary dictionary];
2
3[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
4    if ([key hasPrefix:@"a"]) {
5        filtered[key] = obj;
6    }
7}];
8
9NSLog(@"%@", filtered);

This is often cleaner than trying to mutate the original dictionary in place.

When To Prefer Key Iteration Versus Block Iteration

A useful rule is:

  • use fast enumeration when you mainly care about keys or want the shortest syntax,
  • use block enumeration when you naturally want key and value together or may stop early.

Both are valid. The better choice is the one that makes the control flow clearer.

Performance And Readability

For ordinary app code, performance differences between these enumeration styles are rarely the real issue. Readability and mutation safety matter more.

If your code runs in a hot path, measure before optimizing. Most of the time, the right question is “is the dictionary being modified safely?” not “which loop form is fastest?”

Common Pitfalls

  • Assuming NSMutableDictionary preserves a meaningful order during iteration.
  • Mutating the dictionary directly while fast-enumerating it.
  • Forgetting that fast enumeration gives keys, not key-value tuples.
  • Writing repeated dictionary lookups when block enumeration would be clearer.
  • Depending on iteration order in tests without sorting keys first.

Summary

  • The simplest way to loop through an NSMutableDictionary is fast enumeration over its keys.
  • Use enumerateKeysAndObjectsUsingBlock: when you want both key and value directly.
  • Do not assume dictionary iteration order is stable or sorted.
  • Do not mutate the dictionary directly while fast-enumerating it.
  • If order or safe deletion matters, iterate over a sorted or copied key list.

Course illustration
Course illustration

All Rights Reserved.