19

I want to setup a serialized task queue using NSOperationQueue but I'm a little confused by the terminology discussed in the documentation.

In the context of an NSOperation object, the terms concurrent and non-concurrent do not necessarily refer to the side-by-side execution of threads. Instead, a non-concurrent operation is one that executes using the environment that is provided for it while a concurrent operation is responsible for setting up its own execution environment.

What does it mean to setup "own execution environment'?

My NSOperation derived tasks need to execute serially in the order they were added to the queue.

So I thought that this implies a 'non-concurrent' operation so I'd implement 'main' for the work that needs to be completed and also return NO for 'isConcurrent'. In addition, NSOperationQueue's 'setMaxConcurrentOperationCount' would be set to 1.

The reason I am not setting up NSOperation dependency between these tasks is because the order they're inserted into the queue is the order they should be completed.

Are these assumptions correct?

Alexi Groove
  • 6,646
  • 12
  • 47
  • 54

2 Answers2

28

NSOperationQueue always executes operations concurrently, while taking dependencies into account.

A "non-concurrent" operation requires a separate thread in order to execute concurrently. NSOperationQueue is responsible for providing this thread. In other words, a non-concurrent operation depends on NSOperationQueue to make it a concurrent operation.

A "concurrent" operation is concurrent on its own; it doesn't need NSOperationQueue to create a thread for it. An example would be an operation that uses asynchronous file IO.

If you want two or more operations to execute serially you need to use dependencies.

If you want an operation to block the main thread then don't use NSOperationQueue; just run each operation one after the other on the main thread.

To manually set maximum of concurrent operations, use method on operationQueue setMaxConcurrentOperationCount:

Michal
  • 15,429
  • 10
  • 73
  • 104
Darren
  • 25,520
  • 5
  • 61
  • 71
  • 9
    You don't necessarily need to use dependencies if you setMaxConcurrentOperationCount on your NSOperationQueue to 1. In my experience, it processes operations in the order they were added to the queue. However, you can set up the dependecies just to be safe. – Brad Larson Oct 30 '09 at 04:06
  • 11
    The doc states that setting the max count to 1 alone does not guarantee FIFO order. NSOperationQueue also takes priorities into account and a few other things to determine the order. – Christian Kienle Apr 03 '13 at 07:19
2

Do you really need to subclass NSOperation? Why not just use NSInvocationOperation and its addDependency: method?

See my answer in this SO question.

Community
  • 1
  • 1
nall
  • 15,899
  • 4
  • 61
  • 65
  • So NSInvocationOperation is for lightweight tasks where creating a subclass is overkill.. But what constitutes a "own execution environment"? – Alexi Groove Oct 29 '09 at 23:17
  • Interestingly, that wording is not in the latest version of the documentation (see link below). I believe that wording refers to any setup you need to do with respect to thread creation. https://developer.apple.com/iphone/library/documentation/Cocoa/Reference/NSOperation_class/Reference/Reference.html – nall Oct 29 '09 at 23:32
  • This phrase from the older documentation seems relevant: In your start method, you must prepare the operation for execution, which includes preparing the runtime environment for your operation. (For example, if you wanted to create a thread yourself, you would do it here.) Once your runtime environment is established, you can call any methods or functions you want to subsequently start your operation. – nall Oct 29 '09 at 23:35