100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

NSArray, NSDictionary, and Collections

Working with Objective-C's core collection classes — NSArray, NSDictionary, NSSet — including mutability, enumeration, and common pitfalls.

Memory & Foundation FrameworkBeginner9 min readJul 10, 2026
Analogies

Immutable vs. Mutable Collections

Objective-C's Foundation framework splits every core collection into an immutable base class and a mutable subclass: NSArray and NSMutableArray, NSDictionary and NSMutableDictionary, NSSet and NSMutableSet. An NSArray, once created with arrayWithObjects: or a literal like @[@"a", @"b"], can never have elements added, removed, or replaced — any attempt to call addObject: on a plain NSArray reference will fail to compile, because that method simply isn't declared on NSArray, only on NSMutableArray. This split exists deliberately for safety and performance: an immutable collection can be freely shared across threads without synchronization, and API designers use NSArray as a return type specifically to signal 'you may read this but you may not mutate it,' even when the concrete underlying object happens to be a mutable instance internally.

🏏

Cricket analogy: An NSArray is like the final printed scorecard handed to spectators after the match — fixed and unchangeable — while an NSMutableArray is like the scorer's live working sheet during play, where runs and wickets are still being added ball by ball.

objectivec
NSArray *fixedFruits = @[@"apple", @"banana", @"cherry"];
// [fixedFruits addObject:@"date"]; // compile error: no visible @interface for NSArray declares addObject:

NSMutableArray *cart = [NSMutableArray arrayWithCapacity:4];
[cart addObject:@"apple"];
[cart addObject:@"banana"];
[cart removeObject:@"apple"];
NSLog(@"%@", cart); // ("banana")

NSDictionary *config = @{@"timeout": @30, @"retries": @3};
NSNumber *timeout = config[@"timeout"]; // subscripting syntax

NSMutableDictionary *scores = [NSMutableDictionary dictionary];
scores[@"Alice"] = @95;
scores[@"Bob"] = @87;
[scores removeObjectForKey:@"Bob"];

Enumeration Patterns

Objective-C offers several enumeration styles with different tradeoffs. Fast enumeration (for (id obj in collection)) is compiled down to calls against NSFastEnumeration, making it the fastest and most idiomatic way to iterate when you just need each element in order and don't need the index; it also works uniformly across NSArray, NSSet, and NSDictionary (where it yields keys, not values). When you need the index alongside the object, enumerateObjectsUsingBlock: is preferable to a manual C-style for loop because it gives you both obj and idx directly and supports a stop pointer (*stop = YES;) to break out early — something fast enumeration cannot do cleanly. For NSDictionary, enumerateKeysAndObjectsUsingBlock: avoids the two-step 'get key via fast enumeration, then look up value' pattern and is measurably faster for large dictionaries because it avoids the extra hash lookup per key.

🏏

Cricket analogy: Fast enumeration is like walking down the batting order top to bottom during a straightforward run chase — simple and in order; enumerateObjectsUsingBlock: is like a match analyst who also tracks each batter's position number and can call off further analysis early (*stop = YES;) the moment the required run rate becomes irrelevant, say if rain ends the match.

Never mutate a mutable collection while fast-enumerating it (for (id obj in mutableArray) { [mutableArray removeObject:obj]; }) — this throws NSGenericException 'was mutated while being enumerated' at runtime, because fast enumeration snapshots a mutation counter and checks it hasn't changed on every iteration. If you need to remove items conditionally, either enumerate a copy, collect indices into an NSMutableIndexSet first and remove them after the loop, or use enumerateObjectsUsingBlock: with removeObjectsAtIndexes: applied afterward.

Key-Value Coding, Sorting, and Equality

NSDictionary keys are looked up via -isEqual: and -hash, which means custom objects used as keys must override both methods consistently (equal objects must produce equal hashes) or lookups will silently fail to find entries that logically should match. NSArray provides sortedArrayUsingComparator: and sortedArrayUsingDescriptors: (the latter taking NSSortDescriptor objects, useful for multi-key sorts like sorting Person objects by lastName then firstName) without mutating the original array, since NSArray itself is immutable — you always get a new sorted array back. Key-Value Coding lets you pull an array of values out of a collection of objects in one call using valueForKey:, for example [people valueForKey:@"firstName"] returns an NSArray of every person's firstName, and Foundation even supports collection operators like @avg, @sum, @count, and @max appended to a keypath for quick aggregate computations without writing a manual loop.

🏏

Cricket analogy: NSDictionary key lookup via isEqual:/hash is like matching a player to their stats using both jersey number and team name together — if you only check one attribute inconsistently, you might fail to match Virat Kohli's ODI stats to his T20 stats even though they're the same player.

  • NSArray/NSDictionary/NSSet are immutable; NSMutableArray/NSMutableDictionary/NSMutableSet are their mutable subclasses that add insertion and removal methods.
  • Immutable collections can be safely shared across threads without synchronization, which is why APIs often return NSArray even for internally mutable data.
  • Fast enumeration (for...in) is the fastest and most idiomatic way to iterate in order; enumerateObjectsUsingBlock: adds index access and early-exit via *stop = YES.
  • Mutating a mutable collection while fast-enumerating it throws a runtime exception ('was mutated while being enumerated').
  • NSDictionary key lookups rely on -isEqual: and -hash; custom key objects must override both consistently.
  • sortedArrayUsingDescriptors: with NSSortDescriptor supports multi-key sorting (e.g., lastName then firstName) without mutating the original array.
  • Key-Value Coding's valueForKey: and collection operators (@sum, @avg, @count, @max) let you extract or aggregate values across a collection in one call.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#ObjectiveCStudyNotes#NSArrayNSDictionaryAndCollections#NSArray#NSDictionary#Collections#Immutable#StudyNotes#SkillVeris#ExamPrep