What do Operation and OperationQueue give you that GCD does not, and where does async/await fit?
Predict first
What does this print?
let q = OperationQueue()
q.maxConcurrentOperationCount = 1
let a = BlockOperation { print("A") }
let b = BlockOperation { print("B") }
b.addDependency(a)
q.addOperations([b, a], waitUntilFinished: true)
- B then A
- A then B
- Either order
Predict first
What does this print?
let q = OperationQueue()
let op = BlockOperation { print("ran") }
op.cancel()
q.addOperations([op], waitUntilFinished: true)
print("done")
- ran, done
- done
Mental model. GCD is dropping a task in the in-tray. An OperationQueue is a project plan: this task waits for that one, and any task can be crossed off before it starts.
Operation models a unit of work as an object, so a queue can add dependencies (“run B after A”), priorities, a concurrency limit (maxConcurrentOperationCount), and cancellation. Cancelling is cooperative: cancel() sets isCancelled, and a long operation must check it. An operation that has not started yet when cancelled simply never runs.
An asynchronous operation (one that returns before its work is done) has to manage isExecuting and isFinished itself, with KVO notifications, which is easy to get wrong. GCD is lighter for fire-and-forget blocks; async/await and task groups now cover most dependency and cancellation needs with less ceremony. Reach for OperationQueue for legacy code, explicit dependency graphs, or throttling a pipeline.
The dependency forces B to wait for A, regardless of the order they were added.
An operation cancelled before it starts is skipped: the queue finishes it without running the block.
Common traps
- Assuming
cancel()stops running work. It only flips a flag that your code must check. - A dependency cycle. A depends on B and B on A, so neither ever starts.
They might follow up with
- How do you run strictly one at a time?
maxConcurrentOperationCount = 1, which gives a serial queue. - What does
waitUntilAllOperationsAreFinished()do on the main thread? It blocks the UI. Avoid it.
Related questions
- 2.4.4 NotificationCenter, delegate, closure or KVO: how do you choose?
← How does KVO work in Swift, and why does it sometimes never fire?