I want to use a queue data structure in my Objective-C program. In C++ I'd use the STL queue. What is the equivalent data structure in Objective-C? How do I push/pop items?
10 Answers
Ben's version is a stack instead of a queue, so i tweaked it a bit:
NSMutableArray+QueueAdditions.h
@interface NSMutableArray (QueueAdditions)
- (id) dequeue;
- (void) enqueue:(id)obj;
@end
NSMutableArray+QueueAdditions.m
@implementation NSMutableArray (QueueAdditions)
// Queues are first-in-first-out, so we remove objects from the head
- (id) dequeue {
// if ([self count] == 0) return nil; // to avoid raising exception (Quinn)
id headObject = [self objectAtIndex:0];
if (headObject != nil) {
[[headObject retain] autorelease]; // so it isn't dealloc'ed on remove
[self removeObjectAtIndex:0];
}
return headObject;
}
// Add to the tail of the queue (no one likes it when people cut in line!)
- (void) enqueue:(id)anObject {
[self addObject:anObject];
//this method automatically adds to the end of the array
}
@end
Just import the .h file wherever you want to use your new methods, and call them like you would any other NSMutableArray methods.
-
There is a bug in the dequeue code. I'm going to post a correction below since I can't do it in the comments, but basically objectAtIndex will throw an exception, not return nil if the object doesn't exist. So this code will throw an exception on dequeueing an empty array, rather than returning nil. – DougW Nov 10 '09 at 00:47
-
1I added a commented-out line at the beginning of dequeue for those that wish to return nil rather than raise an exception when trying to dequeue from an empty queue. IMO, following the NSMutableArray behavior of raising an exception is more consistent with Cocoa. After all, you can call `-count` beforehand to check if there are any objects to dequeue. It's a matter of preference, really. – Quinn Taylor Feb 01 '10 at 17:42
-
Wouldn't it be better to create a composite object, instead of using a category on NSMutableArray? That way clients know that objects won't be mucked around with. Composite as in, a queue object with a mutable array as in ivar etc. – Myron Slaw Sep 24 '11 at 02:08
-
2I've added this code to a github repo. Feel free to fork or let me know if I've gotten something wrong: https://github.com/esromneb/ios-queue-object Thanks!!! – benathon Oct 27 '11 at 05:45
-
Thanks @portforwardpodcast I wish I thought of doing that! =P – Wolfcow Dec 06 '11 at 20:24
-
Wolfcow: Your welcome, actually my twitter is @portfwdpodcast, not what you wrote =P Please fork or follow the project if you like it! – benathon Dec 07 '11 at 09:26
-
1@portforwardpodcast the @ notation is a way of directing your comment at a user of that name on stackoverflow. – Rik Smith-Unna Mar 25 '12 at 11:47
-
@portforwardpodcast: something is wrong! you're not doing a retain-autorelease in `dequeue`. it should be `queueObject = [[[self objectAtIndex: 0] retain] autorelease];` – Claudiu Sep 13 '13 at 16:21
-
@Claudiu I think autorelease is illegal with ARC, and if you know how to fix it, just fork the project! – benathon Sep 17 '13 at 21:57
-
@portforwardpodcast: it is, but then you have a bug if ARC is disabled. I do know how to fix but haven't used git or github yet so there's some initial resistance to figuring it out, which is why I just wrote a comment here. someday =) – Claudiu Sep 17 '13 at 22:36
-
1@portforwardpodcast: ok i got around to forking & pull requesting, found a way where it'll work both with ARC and without.. – Claudiu Oct 01 '13 at 23:07
-
1This is the best solution so far. – Envil Feb 24 '14 at 06:21
-
2Am I missing something, or does this implementation have O(n) complexity on dequeue? That's terrible. You'd be much better off with a circular array implementation. this implementation might work, but the idea of O(n) dequeue is painful. – ThatGuy Aug 29 '14 at 18:28
-
@ThatGuy, It's just a simple queue where objects are always removed from the head of the data structure, so yes, if you wanted to dequeue all n objects in the queue, it would be O(n). But on that note, if you are in a situation where you don't care about the item(s) being dequeued, then you could just implement a new empty queue, thus 'removing' all the objects ;) When it comes to removing items from a Queue or a Stack, it is usually O(n), but you could always change the implementation to meet your specific needs if you wanted, this is just a 'typical' queue. – Wolfcow Sep 12 '14 at 05:07
-
11@Wolfcow, when you remove an object from index 0, every object in the array is shifted down one. Therefore, to remove a single item, it is O(n). Probably fine for small queues, which is probably 99% of the time in mobile applications, but this would be a terrible solution for large data sets in time-critical situations. Again, not that you'd find that in most objective C situations. – ThatGuy Sep 15 '14 at 00:51
-
According to the docs NSMutableArray isn't thread safe, so this code could have issues if used in a multi threaded way. You would fix this by only calling on a single thread or adding locks around every accessor/modifier. – Bourne Aug 03 '15 at 20:13
-
2@ThatGuy A little late, but NSArray is implemented with a circular buffer, so the runtime won't be theta(N). – hhanesand May 13 '18 at 21:23
I wouldn't say that using NSMutableArray is necessarily the best solution, particularly if you're adding methods with categories, due to the fragility they can cause if method names collide. For a quick-n-dirty queue, I'd use the methods to add and remove at the end of a mutable array. However, if you plan to reuse the queue, or if you want your code to be more readable and self-evident, a dedicated queue class is probably what you want.
Cocoa doesn't have one built in, but there are other options, and you don't have to write one from scratch either. For a true queue that only adds and removes from the ends, a circular buffer array is an extremely fast implementation. Check out CHDataStructures.framework, a library/framework in Objective-C that I've been working on. It has a variety of implementations of queues, as well as stacks, deques, sorted sets, etc. For your purposes, CHCircularBufferQueue is significantly faster (i.e. provable with benchmarks) and more readable (admittedly subjective) than using an NSMutableArray.
One big advantage of using a native Objective-C class instead of a C++ STL class is that it integrates seamlessly with Cocoa code, and works much better with encode/decode (serialization). It also works perfectly with garbage collection and fast enumeration (both present in 10.5+, but only the latter on iPhone) and you don't have to worry about what is an Objective-C object and what is a C++ object.
Lastly, although NSMutableArray is better than a standard C array when adding and removing from either end, it's also not the fastest solution for a queue. For most applications it is satisfactory, but if you need speed, a circular buffer (or in some cases a linked list optimized to keep cache lines hot) can easily trounce an NSMutableArray.

- 44,553
- 16
- 113
- 131
-
2
-
All the links are broken - where do I get that framework? I have read a lot of good stuff about it but can’t find the actual code! – amok Dec 19 '10 at 04:08
-
The framework sounds promising but the links to SVN are still broken. Any chance to get the code somewhere? EDIT: Got it from http://mac.softpedia.com/progDownload/CHDataStructures-Download-73842.html but I can't see whether this is the current version – Kay May 03 '11 at 20:31
-
Dave DeLong's Git [repo clone](https://github.com/davedelong/CHDataStructures) appears to be the go-to repo these days. – Regexident Mar 06 '14 at 12:41
As far as I know, Objective-C does not provide a Queue data structure. Your best bet is to create an NSMutableArray
, and then use [array lastObject]
, [array removeLastObject]
to fetch the item, and [array insertObject:o atIndex:0]
...
If you're doing this a lot, you might want to create an Objective-C category to extend the functionality of the NSMutableArray
class. Categories allow you to dynamically add functions to existing classes (even the ones you don't have the source for) - you could make a queue one like this:
(NOTE: This code is actually for a stack, not a queue. See comments below)
@interface NSMutableArray (QueueAdditions)
- (id)pop;
- (void)push:(id)obj;
@end
@implementation NSMutableArray (QueueAdditions)
- (id)pop
{
// nil if [self count] == 0
id lastObject = [[[self lastObject] retain] autorelease];
if (lastObject)
[self removeLastObject];
return lastObject;
}
- (void)push:(id)obj
{
[self addObject: obj];
}
@end

- 44,553
- 16
- 113
- 131

- 14,805
- 3
- 42
- 47
-
7
-
-
I'd agree if you replace "best bet" with "simplest option". :-) Data structure purists and performance obsessors would prefer a true queue, but an NSMutableArray can easily stand in for a queue. – Quinn Taylor Jun 16 '09 at 18:43
-
3+1 to ben because I wanted a stack solution even though a queue was asked for :) – whitneyland Aug 29 '11 at 21:52
-
All I can think about is the pain. You are inserting an object at the start of an array, you then need to copy every element over 1 space each time you insert. In this case a linked-list will perform much better. – TheM00s3 Aug 17 '15 at 15:58
There's no real queue collections class, but NSMutableArray can be used for effectively the same thing. You can define a category to add pop/push methods as a convenience if you want.

- 40,399
- 3
- 75
- 82
-
True, an NSMutableArray makes a pretty decent queue, although removing from the front is not something an array structure excels at. Even so, for small queues, performance isn't a major concern anyway. A friend of mine blogged about this topic a while back... http://sg80bab.blogspot.com/2008/05/nsmutablearray-makes-awesome-cocoa.html – Quinn Taylor Jun 16 '09 at 18:41
Yes, use NSMutableArray. NSMutableArray is actually implemented as 2-3 tree; you typically need not concern yourself with the performance characteristics of adding or removing objects from NSMutableArray at arbitrary indices.

- 121
- 2
-
1NSArray (and NSMutableArray by extension) is a class cluster, meaning it has several private implementations that may be used interchangeably behind the scenes. The one you get usually depends on the number of elements. Also, Apple is free to change the details of any given implementation at any time. However, you're correct that it's usually much more flexible than a standard array. – Quinn Taylor Jun 21 '09 at 14:27
re:Wolfcow -- Here is a corrected implementation of Wolfcow's dequeue method
- (id)dequeue {
if ([self count] == 0) {
return nil;
}
id queueObject = [[[self objectAtIndex:0] retain] autorelease];
[self removeObjectAtIndex:0];
return queueObject;
}

- 28,776
- 18
- 79
- 107
The solutions that use a category on NSMutableArray
are not true queues, because NSMutableArray
exposes operations that are a superset of queues. For example, you should not be allowed to remove an item from the middle of a queue (as those category solutions still let you do). It is best to encapsulate functionality, a major principle of object oriented design.
StdQueue.h
#import <Foundation/Foundation.h>
@interface StdQueue : NSObject
@property(nonatomic, readonly) BOOL empty;
@property(nonatomic, readonly) NSUInteger size;
@property(nonatomic, readonly) id front;
@property(nonatomic, readonly) id back;
- (void)enqueue:(id)object;
- (id)dequeue;
@end
StdQueue.m
#import "StdQueue.h"
@interface StdQueue ()
@property(nonatomic, strong) NSMutableArray* storage;
@end
@implementation StdQueue
#pragma mark NSObject
- (id)init
{
if (self = [super init]) {
_storage = [NSMutableArray array];
}
return self;
}
#pragma mark StdQueue
- (BOOL)empty
{
return self.storage.count == 0;
}
- (NSUInteger)size
{
return self.storage.count;
}
- (id)front
{
return self.storage.firstObject;
}
- (id)back
{
return self.storage.lastObject;
}
- (void)enqueue:(id)object
{
[self.storage addObject:object];
}
- (id)dequeue
{
id firstObject = nil;
if (!self.empty) {
firstObject = self.storage.firstObject;
[self.storage removeObjectAtIndex:0];
}
return firstObject;
}
@end

- 3,714
- 6
- 41
- 67
-
one might argue that with certain techniques (i.e. KVC) the internal storage array might be accessed and manipulated directly, but much better than using a category. – vikingosegundo Jul 08 '14 at 00:32
this is my implementation, hope it helps.
Is kind of minimalistic, so you must keep the track of the head by saving the new head at pop and discarding the old head
@interface Queue : NSObject {
id _data;
Queue *tail;
}
-(id) initWithData:(id) data;
-(id) getData;
-(Queue*) pop;
-(void) push:(id) data;
@end
#import "Queue.h"
@implementation Queue
-(id) initWithData:(id) data {
if (self=[super init]) {
_data = data;
[_data retain];
}
return self;
}
-(id) getData {
return _data;
}
-(Queue*) pop {
return tail;
}
-(void) push:(id) data{
if (tail) {
[tail push:data];
} else {
tail = [[Queue alloc]initWithData:data];
}
}
-(void) dealloc {
if (_data) {
[_data release];
}
[super release];
}
@end

- 1,868
- 17
- 13
Is there some particular reason you cannot just use the STL queue? Objective C++ is a superset of C++ (just use .mm as the extension instead of .m to use Objective C++ instead of Objective C). Then you can use the STL or any other C++ code.
One issue of using the STL queue/vector/list etc with Objective C objects is that they do not typically support retain/release/autorelease memory management. This is easily worked around with a C++ Smart Pointer container class which retains its Objective C object when constructed and releases it when destroyed. Depending on what you are putting in the STL queue this is often not necessary.

- 17,664
- 2
- 43
- 56
-
1This doesn't really seem like a good idea... just because you *can* do something doesn't mean you should. Pulling in the entire STL and C++ ecosystem just for a queue class is definitely overkill. – n s Nov 05 '13 at 22:13
-
3Actually, since that was posted, this has become a much better idea. Objective C++/ARC means that you can use STL containers with Objective C object pointers and it all just works. ARC takes care of the memory management automatically for you within C++ structures. I would also generally argue that C++, being a much better C, makes Objective-C++ a better choice in general than plain Objective C (giving such things as enum class for example). And I very much doubt adding STL/C++ has any noticeable impact on size of any real world app. – Peter N Lewis Nov 06 '13 at 02:52