NSOperation
NSOperation is a higher level version of GCD which I talk about in my previous post. It’s an abstract class that offers a thread-safe structure for thread management, priority, dependencies and state. In order to make your application quick and responsive, it’s necessary to work on a background thread using NSOperation or GCD, or even both.
NSOperationQueue regulates the concurrent execution of operations by working in a FIFO (first-in-first-out) order. It can limit the max number of operations to be executed at any given moment (NSOperation.maxConcurrentOperationCount). To start an operation you can call NSOperation.start or add the operation to the queue. You are able to subclass an NSOperation to perform a specific task.
States
A difference between GCD and NSOperation is that NSOperation has an easy description for its state of operation.
- ready — Returns true to indicate that the operation is ready to execute.
- executing — Return true if the task is currently being ran.
- finished — Returns true if the operation’s task finished execution successfully.
Priority & Quality of Service
Priority (NSOperation.queuePriority) is as enum with the options of:
- .VeryLow
- .Low
- .Normal
- .High
- .VeryHigh
Quality of service (NSOperation.qualityOfService) has the options of:
- .Utility
- .UserInteractive
- .UserInitiated
- .Default.
- .Background
The lower the priority and quality of service, the farther back the task will move in the queue in comparison to other tasks.
Dependencies
let operationOne: NSOperation = …let operationTwo: NSOperation = …operationTwo.addDependency(operationOne)let operationQueue = NSOperationQueue.mainQueue()operationQueue.addOperation([operationOne, operationTwo], waitUntilFinished: false)
In this case, operationTwo is dependent on operationOne, therefore operationTwo cannot run until operationOne is completed. Make sure not to make operationOne depend on operationTwo and operationTwo depend on operationOne or this will create a deadlock.
Completion Block
When an NSOperation is completed, it will run its completion block once.
let operation = NSOperation()operation.completionBlock = {print(“Done!”)}NSOperationQueue.mainQueue().addOperation(operation)
NSBlockOperation
Block operations are similar to operations, but can take the tasks in the block instead of subclassing the operation.
This would add operation2 into the queue and then add operation1 to the queue. It would first execute operation2’s block and then operation1's.
GCD vs NSOperation
Good times to use GCD:
- For one computation
- To speed up an existing method
- In need of something lightweight
Good times to use NSOperation:
- Need to be cancelled and aware of it’s operational state
- Need to be scheduled with a set of dependencies
Using both GCD and NSOperation together can enable your application to be very sleek.
Follow me on twitter @anthonyprograms and check out The iOS Chroniclesfor more articles.