Swift Language Creating High-Level Operations


Example

The Foundation framework provides the Operation type, which represents a high-level object that encapsulates a portion of work that may be executed on a queue. Not only does the queue coordinate the performance of those operations, but you can also establish dependencies between operations, create cancelable operations, constrain the degree of concurrency employed by the operation queue, etc.

Operations become ready to execute when all of its dependencies are finished executing. The isReady property then changes to true.

Create a simple non-concurrent Operation subclass:

3.0
class MyOperation: Operation {

    init(<parameters>) {
        // Do any setup work here
    }

    override func main() {
        // Perform the task
    }

}
2.3
class MyOperation: NSOperation {

    init(<parameters>) {
        // Do any setup work here
    }

    override func main() {
        // Perform the task
    }

}

Add an operation to an OperationQueue:

1.0
myQueue.addOperation(operation)

This will execute the operation concurrently on the queue.

Manage dependencies on an Operation.

Dependencies define other Operations that must execute on a queue before that Operation is considered ready to execute.

1.0
operation2.addDependency(operation1)

operation2.removeDependency(operation1)

Run an Operation without a queue:

1.0
   operation.start()

Dependencies will be ignored. If this is a concurrent operation, the task may still be executed concurrently if its start method offloads work to background queues.

Concurrent Operations.

If the task that an Operation is to perform is, itself, asynchronous, (e.g. a URLSession data task), you should implement the Operation as a concurrent operation. In this case, your isAsynchronous implementation should return true, you'd generally have start method that performs some setup, then calls its main method which actually executes the task.

When implementing an asynchronous Operation begins you must implement isExecuting, isFinished methods and KVO. So, when execution starts, isExecuting property changes to true. When an Operation finishes its task, isExecuting is set to false, and isFinished is set to true. If the operation it is cancelled both isCancelled and isFinished change to true. All of these properties are key-value observable.

Cancel an Operation.

Calling cancel simply changes the isCancelled property to true. To respond to cancellation from within your own Operation subclass, you should check the value of isCancelled at least periodically within main and respond appropriately.

1.0
operation.cancel()