Objective-C
NSSet
NSArray
Data Structures
iOS Development

When is it better to use an NSSet over an NSArray?

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

NSArray and NSSet both store Objective-C objects, but they make different guarantees. NSArray preserves order and supports index-based access, while NSSet enforces uniqueness and is optimized for membership-style operations. The better choice depends on what your code needs the collection to mean.

What NSArray Is For

An NSArray is an ordered collection. If element position matters, an array is usually the correct abstraction.

That makes NSArray a good fit when:

  • you care about insertion order or sorted order
  • duplicates are valid data
  • you need indexed access
  • the collection maps directly to UI presentation

Example:

objective-c
1NSArray<NSString *> *steps = @[@"Open", @"Edit", @"Save"];
2NSLog(@"First step: %@", steps[0]);
3
4for (NSString *step in steps) {
5    NSLog(@"%@", step);
6}

This code depends on order. The first item means something different from the third item. A set would not preserve that meaning.

What NSSet Is For

An NSSet is an unordered collection of unique objects. Its strongest use case is when the main question is whether an object is present, not where it appears.

Example:

objective-c
1NSSet<NSString *> *allowedRoles = [NSSet setWithArray:@[@"admin", @"editor", @"viewer"]];
2
3if ([allowedRoles containsObject:@"editor"]) {
4    NSLog(@"Role is allowed");
5}

This is a natural use of a set because order does not matter and duplicates would be meaningless.

Use NSSet When Uniqueness Is Part of the Data Model

A set is usually better when duplicates would represent invalid or useless state. Common examples include:

  • currently enabled feature flags
  • unique tags on a record
  • a set of processed identifiers
  • visited nodes during graph traversal
objective-c
1NSMutableSet<NSNumber *> *visitedUserIDs = [NSMutableSet set];
2[visitedUserIDs addObject:@42];
3[visitedUserIDs addObject:@42];
4
5NSLog(@"Count: %lu", (unsigned long)visitedUserIDs.count);

The count stays 1 because a set refuses to store the duplicate value as a second element.

This behavior is not just about saving space. It makes the collection communicate intent. If the same id appearing twice would be a bug, a set encodes that rule directly.

Use NSArray When Sequence Matters

An array is better when the collection represents a sequence rather than just a bag of values.

Examples:

  • recent notifications in chronological order
  • ranked search results
  • a playlist
  • table rows displayed in a particular sequence
objective-c
1NSMutableArray<NSString *> *playlist = [NSMutableArray arrayWithArray:@[@"Intro", @"Theme", @"Outro"]];
2[playlist insertObject:@"Interlude" atIndex:1];
3
4for (NSUInteger i = 0; i < playlist.count; i++) {
5    NSLog(@"%lu: %@", (unsigned long)i, playlist[i]);
6}

That style of code is what arrays are designed for. Using a set here would force you to recreate order elsewhere, which usually means you chose the wrong structure.

Membership Testing and Performance

In practical code, the biggest performance distinction is membership lookup. Arrays usually require a scan to answer "does this object exist," while sets are designed for much faster lookup on average.

objective-c
1NSArray<NSString *> *array = @[@"a", @"b", @"c", @"d"];
2NSSet<NSString *> *set = [NSSet setWithArray:array];
3
4BOOL inArray = [array containsObject:@"d"];
5BOOL inSet = [set containsObject:@"d"];
6
7NSLog(@"Array: %@, Set: %@", inArray ? @"YES" : @"NO", inSet ? @"YES" : @"NO");

Both give the same logical answer, but the structures are optimized for different workloads.

Still, performance should not be the only criterion. Semantics matter more. If the collection is conceptually ordered, use an array. If uniqueness and membership are the point, use a set.

When NSOrderedSet Is the Better Answer

Sometimes the real requirement is both uniqueness and stable order. In that case, neither NSArray nor NSSet is perfect by itself. NSOrderedSet exists for exactly that situation.

objective-c
NSOrderedSet<NSString *> *orderedTags = [NSOrderedSet orderedSetWithArray:@[@"ios", @"swift", @"ios"]];
NSLog(@"%@", orderedTags);

This preserves the original order of the first occurrence while removing duplicates. It is often the right answer when developers are otherwise tempted to combine an array and a set manually.

Common Pitfalls

The most common mistake is using NSSet for data that really needs a stable order, then being surprised that iteration order is unsuitable for UI or deterministic output. Another is using NSArray for large collections where the dominant operation is membership testing, which causes unnecessary repeated scans. Developers also sometimes convert an array to a set just to remove duplicates and then forget that all ordering information has been lost. A final issue is ignoring NSOrderedSet when both uniqueness and ordering are real requirements.

Summary

  • Use NSArray when order, indexing, or duplicates matter.
  • Use NSSet when uniqueness and fast membership checks matter.
  • Pick the collection that matches the meaning of the data, not just one operation's speed.
  • 'NSSet is a strong fit for lookup-heavy and uniqueness-heavy logic.'
  • If you need both order and uniqueness, NSOrderedSet is often the best fit.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.