We just explored DispatchQueues and how we can use them 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, we're going to take this all one step further. The first reason for this is because our asynchronous work would be better organized if we had an object that we could schedule for execution rather than a closure. Closures pollute code and they are much harder to reuse.
The solution to this is using an Operation instead of a closure. And instead of queueing everything in a dispatch queue, we should queue Operation instances on an OperationQueue. The OperationQueue and the DispatchQueue are similar, but not quite the same. An OperationQueue can schedule Operations on one or more DispatchQueue. This is important because of the way in which Operations work.
Using an OperationQueue, you can execute Operations in parallel or serially. It is also possible to specify dependencies for Operations. This means that we can make sure that certain Operations are completed before the next operation is executed. The OperationQueue will manage the DispatchQueues needed to make everything happen, and it will execute the Operations in the order in which they become ready to execute.
The next section will briefly cover some of the basic concepts of Operations.