-
Notifications
You must be signed in to change notification settings - Fork 0
01 — Why GCD Exists
Imagine a restaurant before it had any real staffing system.
Every single order gets its own personal chef 🧑🍳, hired on the spot.
-
Order comes in → hire a chef 👋
-
Chef cooks the order 🍔
-
Order is done → fire the chef 👋💨
-
Next order comes in → hire a new chef again...
-
Ten orders at once? Ten chefs, hired and fired on the spot 😵
-
A thousand orders? The restaurant collapses under its own hiring paperwork
👉 This is what programming looked like before GCD: one thread, manually created, per unit of work.
Before GCD existed (pre-2009, pre-iOS 4, pre-Mac OS X Snow Leopard), concurrency meant managing threads by hand:
-
Thread/NSThread— create, configure, and start a thread yourself -
pthread— the raw POSIX thread API, even lower-level
With these tools, you were the hiring manager:
- You decided how many threads to create
- You sized the thread pool yourself, guessing at the "right" number
- Too few threads → work piles up, the app feels sluggish
- Too many threads → wasted memory, and the CPU burns time just switching between threads instead of doing work
There was no shared system smart enough to say "let's not hire a new chef for every order."
Then, in 2009, Apple introduced Grand Central Dispatch (GCD).
GCD's big idea: stop managing threads yourself. Instead:
- You submit blocks of work to a queue 🧾
- The system owns a shared, managed thread pool 👨🍳👩🍳
- The system decides how many threads to actually use, based on available cores and system load
You stopped being the hiring manager. The kitchen now manages a shared team of chefs for you.
BEFORE GCD — Hire a chef per order 😵
📋 Order 1 → hire 🧑🍳 → serve → fire 💨
📋 Order 2 → hire 🧑🍳 → serve → fire 💨
📋 Order 3 → hire 🧑🍳 → serve → fire 💨
💸 Constant hiring/firing overhead, no shared plan
AFTER GCD — Submit to a queue, staff is managed 🎉
📋 Order 1 ──┐
📋 Order 2 ──┼──> 🧾 Queue ──> 👨🍳👩🍳 (shared, system-managed pool)
📋 Order 3 ──┘
💡 The system decides how many chefs are actually needed
You used to have to spin up and manage threads yourself:
// Old style — manual thread management (no longer necessary)
let thread = Thread {
print("Order 1 🍔")
}
thread.start()With GCD, you just submit the work — the system manages the threads:
// GCD: just submit work, the system manages the threads
DispatchQueue.global().async {
print("Order 1 🍔")
}👉 No hiring. No firing. Just hand the order to the queue.
GCD solved one problem really well: thread management. You no longer had to hand-size a thread pool — the system did it for you.
Swift Concurrency (introduced in 2021) runs on a similarly system-managed, cooperative thread pool — but it exists to solve a different, higher-level set of problems:
- Structured task lifecycle — tasks have clear parents, children, and scopes
- Cancellation — cancellation propagates automatically through a task tree
- Data-race safety — the compiler checks for unsafe shared mutable state
👉 GCD answers "who runs this work?" Swift Concurrency answers "how do I structure, cancel, and safely share data across this work?"
GCD replaced hand-hiring a chef per order with a shared team of chefs the kitchen manages for you.
A restaurant's staff size is usually something a manager sets and adjusts occasionally.
GCD's thread pool is far more dynamic than that:
- It grows and shrinks in real time, per task
- It's driven by Quality of Service (QoS) and current system load, not a fixed headcount
So "a shared team of chefs" captures the shift in responsibility — but not how fluid and automatic the actual sizing really is.
If every order got its own hand-hired, hand-fired chef, what happens to the restaurant as order volume grows — and why doesn't that scale?