You have just learned about DispatchQueues, and how they are used to schedule tasks that need to be performed on a different thread. You saw how this speeds up code and how it avoids blocking the main thread. In this section, you will take this one step further. The first reason for this is because asynchronous work is better organized if it is implemented as an isolated object that can be scheduled for execution instead of having several closures that make your code less readable.
The solution to having closures all over your asynchronous code is to use Operation instead of a closure. And instead of queueing everything in a dispatch queue, Operation instances are queued on OperationQueue. OperationQueue and DispatchQueue are similar, but not quite the same. OperationQueue can schedule Operations on one or more DispatchQueues. This is important because of the way in which Operations work.
When using OperationQueue, you can execute Operations in parallel or serially. It is also possible to specify dependencies for Operations. This means that you can make sure that certain Operations are completed before the next operation is executed. OperationQueue will manage the DispatchQueues needed to make everything happen, and it will execute Operations in the order in which they become ready to execute. Moreover, code that uses Operations will typically be easier to maintain and understand because all work is beautifully encapsulated in isolated building blocks.
The next section will briefly cover some of the basic concepts of Operations.