GCD vs Async/Await:Swift Concurrency 到底改變了什麼?
很多 iOS 工程師在面試被問到:
GCD 跟 async/await 差在哪?
通常會回答:
- GCD 是 callback-based
- async/await 比較好讀
- async/await 是新的寫法
但如果答案只停在這裡,其實代表:
你還沒真正理解 Swift Concurrency 在解決什麼問題。
因為 async/await 的重點從來不是:
語法變漂亮
而是:
Swift 開始正式處理「Concurrency Complexity(並發複雜度)」。
1. GCD 真正解決的是「Thread Management」
先回到最早期。
在沒有 GCD 的年代,開發者需要自己管理:
- thread creation
- thread scheduling
- synchronization
- locking
這非常痛苦。
所以 Apple 推出了:
GCD(Grand Central Dispatch)
核心目標是:
幫你管理 thread queue
例如:
DispatchQueue.global().async {
print("background work")
}
或:
DispatchQueue.main.async {
self.reloadUI()
}
GCD 很強。
但它有一個根本問題:
它只解決了「thread」,沒有解決「state complexity」
2. Callback Hell 其實不是最大問題
很多文章會說:
async/await 是為了解決 callback hell
例如:
fetchUser {
fetchPosts {
fetchComments {
reloadUI()
}
}
}
沒錯。
但這只是表面問題。
真正可怕的是:
你開始無法推理 execution flow
例如:
- 哪段 code 在 main thread?
- 哪段 code 在 background?
- callback 什麼時候回來?
- state 是不是已經改變?
- object 還活著嗎?
- closure 有沒有 retain cycle?
這些才是真正的 concurrency complexity。
3. GCD 最大問題:Concurrency 是「無結構的」
看這段:
DispatchQueue.global().async {
let result = fetchData()
DispatchQueue.main.async {
self.updateUI(result)
}
}
看起來很正常。
但問題其實很多:
- thread hopping
- callback nesting
- lifecycle 不明
- cancellation 困難
- ownership 不清楚
而且:
GCD 不知道任務之間的關係
這很重要。
4. Async/Await 真正帶來的是「Structured Concurrency」
這才是核心。
Swift Concurrency 最重要的不是 async/await。
而是:
Structured Concurrency
什麼意思?
以前:
任務是亂飛的
現在:
任務開始有「結構」
例如:
func loadData() async {
let user = await fetchUser()
let posts = await fetchPosts(user)
await MainActor.run {
self.reloadUI(posts)
}
}
現在:
- execution flow 可讀
- task relationship 清楚
- suspension point 明確
- lifecycle 可追蹤
這不是語法糖。
這是:
Concurrency Model 的改變
5. await 不是「等待」,而是「暫停」
這是超多人誤解的地方。
很多人以為:
await fetch()
代表:
卡住 thread 等結果
其實不是。
真正發生的是:
函式被 suspend(暫停)
thread 可以去做別的事。
等資料回來後:
Swift Runtime 再恢復 execution
所以 async/await 的效能關鍵其實是:
cooperative suspension
不是 thread blocking。
6. MainActor 為什麼重要?
以前 GCD:
DispatchQueue.main.async {
self.reloadUI()
}
現在:
@MainActor
func reloadUI() {
}
這個差異非常大。
以前:
你要自己記得切 thread
現在:
Swift 開始幫你管理 isolation
這代表:
Concurrency 不再只是 thread 問題,而是 data isolation 問題
這也是為什麼:
Actor 會出現
7. Actor 到底解決什麼?
以前:
var count = 0
多 thread:
count += 1
可能 crash。
因為:
shared mutable state
以前做法:
- lock
- semaphore
- serial queue
現在:
actor Counter {
var count = 0
}
Swift 開始用:
isolation model
避免 data race。
8. Async/Await 不代表沒有問題
很多人以為:
用 async/await 就安全了
其實完全不是。
例如:
Task {
await self.fetch()
}
還是可能:
- retain cycle
- task leak
- state race
- cancellation 問題
因為 concurrency 的本質問題其實是:
state coordination
不是 syntax。
9. 真正危險的是「Task 無限成長」
這是現在很多 SwiftUI 專案開始出現的新問題。
例如:
.onAppear {
Task {
await loadData()
}
}
畫面進出多次:
Task 不斷累積
如果:
- 沒 cancellation
- 沒 lifecycle control
- 沒 isolation
很容易:
- memory leak
- duplicated request
- outdated state
所以 Swift Concurrency 真正重要的是:
Task lifecycle management
10. 面試真正想考的是什麼?
GCD vs Async/Await 這題真正考的其實是:
你是否理解「Concurrency Complexity」
包括:
- state synchronization
- task lifecycle
- data isolation
- cancellation
- ownership
- thread safety
真正成熟的工程師,不會只說:
async/await 比較好讀
而是會知道:
Swift 正在從 thread-based concurrency,走向 state-safe concurrency
結論
GCD 解決的是:
thread scheduling
而 Swift Concurrency 真正想解決的是:
shared mutable state complexity
所以 async/await 的本質從來不是:
新語法
而是:
Swift 開始重新定義「並發程式設計」該怎麼被管理。
延伸思考
如果你開始深入:
- Actor
- MainActor
- TaskGroup
- Sendable
- Isolation
- TCA Effect
- SwiftUI state flow
你會發現:
Swift 的方向其實越來越明顯:
減少不可預測的共享狀態。
因為:
Concurrency 最大的敵人從來不是 thread
而是 state。














