Grand Central Dispatch (GCD): จัดการ Concurrency บน Apple Platforms
GCD เป็นเทคโนโลยีระดับระบบสำหรับจัดการ Thread และ Concurrent Execution บน macOS และ iOS ประกอบด้วย:
- Extension ภาษา C (Blocks)
- API สำหรับ Dispatch Queue
- Runtime Library จัดการ Thread Pool
Block (Closure ใน Swift)
Block คือหน่วยงานอิสระที่เก็บโค้ดและ Context ไว้ร่วมกัน
// C Block Syntax
^{ printf("This is a block"); }
// Swift Closure (Equivalent)
{ print("This is a closure") }
Dispatch Queue: สองประเภท
1. Serial Queue (FIFO)
- Task ทำงานทีละอย่าง ต้องจบก่อนถึงจะทำอันถัดไป
- แต่ละ Process มี Main Queue (Serial) ของตัวเอง - ใช้สำหรับ UI Updates
- สร้างเพิ่มได้:
DispatchQueue(label: "com.myapp.serial")
2. Concurrent Queue (Parallel)
- Task หลายอย่างทำงานพร้อมกันได้ (ขึ้นอยู่กับ Core ที่ว่าง)
- System-wide 3 ระดับ Priority:
- High:
DispatchQueue.global(qos: .userInteractive) - Default:
DispatchQueue.global(qos: .default) - Low:
DispatchQueue.global(qos: .background)
- High:
ตัวอย่างการใช้งานใน Swift
Async บน Global Queue (Background Work)
DispatchQueue.global(qos: .default).async {
// Heavy work: download, parse JSON, compute
let result = heavyComputation()
// Back to Main Queue for UI Update
DispatchQueue.main.async {
self.label.text = "Result: \(result)"
}
}
Sync (Blocking) - ใช้ด้วยความระมัดระวัง
// ⚠️ อย่าเรียกบน Main Queue! จะ Deadlock
let result = DispatchQueue.global().sync {
return heavyComputation()
}
DispatchWorkItem: ควบคุมงานได้ละเอียด
let workItem = DispatchWorkItem {
print("Work executed")
}
DispatchQueue.global().async(execute: workItem)
workItem.cancel() // ยกเลิกได้ถ้ายังไม่เริ่ม
DispatchGroup: รอหลายงานพร้อมกัน
let group = DispatchGroup()
group.enter()
fetchUser { group.leave() }
group.enter()
fetchPosts { group.leave() }
group.notify(queue: .main) {
print("Both finished - Update UI")
}
DispatchSemaphore: Synchronization
let semaphore = DispatchSemaphore(value: 0)
DispatchQueue.global().async {
doWork()
semaphore.signal()
}
semaphore.wait() // Block จนกว่า signal
Quality of Service (QoS) Classes
| QoS Class | Priority | Use Case |
|---|---|---|
| .userInteractive | Highest | UI, Animation, User-facing |
| .userInitiated | High | User-triggered async work |
| .default | Medium | General background work |
| .utility | Low | Long-running, progress可报告 |
| .background | Lowest | Maintenance, Prefetch, Backup |
Best Practices
- ✅ UI Updates ต้องอยู่ Main Queue เสมอ
- ✅ ใช้ QoS ให้เหมาะสมกับความสำคัญของงาน
- ✅ หลีกเลี่ยง
syncบน Main Queue - ✅ ใช้
DispatchGroupแทน Nested Completion Handlers - ✅ Profile ด้วย Instruments (Time Profiler, Thread State)
GCD vs OperationQueue
GCD: Lower-level, C-based, เร็วกว่า เหมาะงานง่าย
OperationQueue: Higher-level, Objective-C/Swift Object-oriented, รองรับ Dependency, KVO, Cancellation, Priority ดีกว่า