Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> iOS

Grand Central Dispatch (GCD) บน iOS และ macOS

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)

ตัวอย่างการใช้งานใน 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 ClassPriorityUse Case
.userInteractiveHighestUI, Animation, User-facing
.userInitiatedHighUser-triggered async work
.defaultMediumGeneral background work
.utilityLowLong-running, progress可报告
.backgroundLowestMaintenance, 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 ดีกว่า