What is a task? GCD
In Swift, this is usually a closure (a block of code).
What is queue? GCD
A queue is an ordered list of tasks.
Tasks are submitted as closures to the queue in a first-in, first-out (FIFO) order
What is GCD? GCD
Grand Central Dispatch: a low-level C API to schedule work on queues and utilize multicore concurrency.
what is a thread? GCD
Is the system-level execution context (in the CPU) where a task runs.
Main vs global queues? GCD
Main queue = main thread (UI). Global queues = background concurrent (non-UI).
Difference between Queue and Thread in GCD
Queue → an ordered list of tasks (FIFO).
Thread → a system resource (execution context on the CPU).
GCD takes tasks from a queue and assigns them to threads as needed.
As a developer, you say “run this on queue Y,” and GCD decides the thread.
How to dispatch work to the main queue? GCD
DispatchQueue.main.async { /* UI updates */ }sync vs async on a queue? GCD
sync blocks caller until finished; async returns to caller immediately.
Serial vs concurrent queue? GCD
Serial runs one task at a time (only on thread is assigned)
Concurrent runs multiple threads (as much as the system has resources for) simultaneously.
Create a serial queue GCD
let q = DispatchQueue(label: "com.acme.serial")
q.async {
// runs off the caller thread, tasks execute one-by-one
let result = heavyWork()
DispatchQueue.main.async {
updateUI(with: result)
}
}
q.sync {
// blocks the current thread until this finishes
doSomething()
}Create a concurrent queue GCD
let q = DispatchQueue(label: "com.acme.concurrent", attributes: .concurrent)
QoS purpose GCD
Hint to system about priority: .userInteractive, .userInitiated, .utility, .background.
Set QoS on queue GCD
let q = DispatchQueue(label: "work", qos: .userInitiated)
Why avoid heavy work on main? GCD
Blocks rendering/input → jank or ANRs (app not responding)
What is a barrier block? GCD
If you have shared mutable state (e.g. a variable state), concurrent reads are fine, but concurrent writes (or read+write) can corrupt data.
Exclusive block on concurrent queue; acts like a write lock.
Barrier example GCD
let q = DispatchQueue(label: "state", attributes: .concurrent)
q.async(flags: .barrier) {
state = .ready
}Delay work with GCD GCD
DispatchQueue.main.asyncAfter(deadline: .now()+0.3) {
...
}What is DispatchGroup? GCD
Group async tasks; get notified when all complete.
DispatchGroup example GCD
let group = DispatchGroup()
for url in urls {
group.enter()
fetch(url) { _ in
g.leave()
}
}
g.notify(queue: .main){
done()
}What is wait in a DispatchGroup?
A synchronous method that will block the current queue until all the jobs have finished.
let group = DispatchGroup()
someQueue.async(group: group) { ... }
someQueue.async(group: group) { ... }
someOtherQueue.async(group: group) { ... }
if group.wait(timeout: .now() + 60) == .timedOut {
print("The jobs didn’t finish in 60 seconds")
}Note: Remember, this blocks the current thread; never ever call wait on the main queue.
Code the following: GCD
- serial queue
- async queue
- main queue
- global
Serial: (you create)
let serialQ = DispatchQueue(label: "com.example.serial")
Concurrent: (you create)
let concurrentQ = DispatchQueue(label: "com.example.concurrent", attributes: .concurrent)
Main: (system-provided)(not concurrent)
let mainQ = DispatchQueue.main
Global: (system-provided) (concurrent)
let globaQ = DispatchQueue.global(qos: .userInitiated)
What is DispatchSemaphore? GCD
Counting semaphore to limit concurrency. (If you wish to enable four network downloads at once, then you pass in 4)
OR
bridge callbacks (use sparingly).
Semaphore limit example GCD
let sem = DispatchSemaphore(value: 3)
for job in jobs {
DispatchQueue.global().async {
sem.wait()
doWork(job)
sem.signal()
}
}Self-deadlock pattern GCD
Calling sync on the same serial queue you’re on.