I'm trying to create a NSOperationQueue and add a NSOperation to it. Later I wan't to check if the queue is running and maybe abort it. All of that is supposed to be called from within different functions. What's the best approach to do this? I would be glad for a code example. Thanks!
-
1It doesn't really answer your question but Grand Central Dispatch offer global queues out of the box. – gcamp May 15 '12 at 15:28
-
This could be the answer I was looking for. Thank you very much! – Linus May 15 '12 at 15:29
-
I managed to create and add a queue but I can't figure out how to cancel a task in the queue. – Linus May 15 '12 at 16:51
-
That's one of the caveats of GCD. http://stackoverflow.com/questions/5449469/can-you-use-cancel-iscancelled-with-gcd-dispatch-async – gcamp May 15 '12 at 18:15
2 Answers
I would create an operation queue that's managed by a singleton.
First, create your singleton class. It will provide access to the NSOperationQueue
. Let's call the singleton MyGlobalQueueManager
.
It will have an ivar
called myGlobalQueue
:
@property (nonatomic) NSOperationQueue* myGlobalQueue;
In the .m
file of MyGlobalQueueManager
, create a fairly standard init
method that will set up the operation queue:
- (id)init
{
self = [super init];
if (self)
{
myGlobalOperationQueue = [[NSOperationQueue alloc] init];
}
return self;
}
Now, the method that provides itself as a singleton. Again, this is pretty standard stuff:
+ (MyGlobalQueueManager *)sharedInstance
{
static MyGlobalQueueManager *sharedInstance = nil;
static dispatch_once_t isDispatched;
dispatch_once(&isDispatched, ^
{
sharedInstance = [[MyGlobalQueueManager alloc] init];
});
return sharedInstance;
}
Let's access that queue from wherever you want to use it:
MyGlobalQueueManager* myGlobalQueueManager = [MyGlobalQueueManager sharedInstance];
NSOperationQueue *myGlobalQueue = myGlobalQueueManager.myGlobalOperationQueue;
You can then add operations to that queue as you fancy.
How to know if anythings queued?
NSUInteger count = [myGlobalQueue operationCount];
How to abort? Cancel everything as follows:
[myGlobalQueue cancelAllOperations];
Cancelling of course depends on the operations. If you're writing custom NSOperation
classes, you'll need to handle that yourself.
I find NSOperation
and NSOperationQueue
to be fairly easy to use and quite straightforward.
A great document to read for all this is the Concurrency Programming Guide. Specifically, have a look at Operation Queues

- 26,115
- 13
- 104
- 132
-
Hey @Max MacLeod if I have two uicontrollers and in first in viewWillDisappear call function cancelAllOperations on Singleton's Queue will it make effect on NSOpearation that I start in 2nd viewcontroller's viewdidload where first is pushing 2nd by navigation controller? – Łukasz Szpyrka Jul 23 '14 at 13:48
-
1In that case I would have a queue in each view controller. Otherwise it becomes more complicated. Have a look at the MVCNetworking sample project provided by Apple. It demonstrates a network manager singleton that operates three or four different queues. – Max MacLeod Jul 23 '14 at 14:32
An easier way to do it is to make a "globally visible" function. AKA, declare it in a public header:
extern NSOperationQueue * SharedQueue();
and define it within your compilation "unit" - but outside any @implementation
.
NSOperationQueue *SharedOperationQueue()
{
static NSOperationQueue * _SharedQueue = nil;
return _SharedQueue ?: ^{ _SharedQueue = NSOperationQueue.new;
_SharedQueue.maxConcurrentOperationCount = NSOperationQueueDefaultMaxConcurrentOperationCount;
return _SharedQueue;
}();
}
As a little bonus.. #define
it with an "alias".. and you can REALLy abuse it!
#define MY_SOQ SharedOperationQueue()
[MY_SOQ addOperationWithBlock:^{ /* GO CRAZY */ }];

- 16,007
- 9
- 96
- 118