--- name: swift-concurrency-6-2 description: Swift 6.2 易用併發模式 — 預設單線程、顯式標註 @concurrent 以進行背景負載平衡,以及針對 MainActor 類型的隔離型協定(Isolated Conformances)。 --- # Swift 6.2 易用併發模式 (Approachable Concurrency) 這是採用 Swift 6.2 併發模型的實踐模式。在該模型中,程式碼預設在單線程運行,僅在顯式標註時才引入併發。這能消除常見的資料競爭 (Data-race) 錯誤,同時不犧牲效能。 ## 何時啟用 - 將 Swift 5.x 或 6.0/6.1 專案遷移至 Swift 6.2。 - 解決編譯器回報的資料競爭安全錯誤。 - 設計基於 `@MainActor` 的應用程式架構。 - 需要將消耗大量 CPU 的工作移至背景線程處理。 - 在 MainActor 隔離類型上實作協定順應性 (Protocol Conformances)。 ## 核心概念:預設單線程行為 在 Swift 6.1 之前的版本中,`async` 函式可能會被隱含地移至背景線程,導致即使是看似安全的程式碼也會觸發資料競爭。 **Swift 6.2 修正了這一點**:非同步函式預設會保留在「調用者」所在的 Actor 上(通常是 MainActor)。 ### 核心模式 1 — 隔離型協定 (Isolated Conformances) MainActor 類型現在可以安全地順應非隔離的協定: ```swift protocol Exportable { func export() } // Swift 6.2:使用隔離性順應性,編譯器保證該協定內容僅在 MainActor 上執行 extension StickerModel: @MainActor Exportable { func export() { photoProcessor.exportAsPNG() } } ``` ### 核心模式 2 — 顯式背景處理 `@concurrent` 當你真正需要平行處理效能時,顯式使用 `@concurrent` 標記將任務移交給併發線程池: ```swift nonisolated final class PhotoProcessor { // 顯式將耗時作業移至背景 @concurrent static func extractSubject(from data: Data) async -> Sticker { /* 處理邏輯 ... */ } } // 調用者必須使用 await let sticker = await PhotoProcessor.extractSubject(from: data) ``` ## 遷移建議 1. **Xcode 設定**:在 Build Settings 的 Swift Compiler -> Concurrency 區段啟用相關功能。 2. **預設使用 MainActor**:建議應用程式 Target 啟用「預設推斷 MainActor」模式,減少手動標記範本代碼。 3. **優化熱點路徑**:先進行測速效能分析 (Profile),僅針對真正的效能瓶頸(如圖片處理、大型計算)才掛上 `@concurrent`。 ## 實踐之最佳實踐 - **從 MainActor 開始**:優先撰寫單線程程式碼,優化留到最後。 - **僅針對運算密集型工作使用 `@concurrent`**:如編碼、壓縮、複雜算法。 - **相信編譯器**:如果編譯器報告資料競爭,則代表程式碼邏輯確實存在併發風險,請勿試圖使用 `nonisolated` 掩蓋問題。 ## 應避免的反模式 - 對每一個 `async` 函式都標記 `@concurrent`(大多數情況下並不需要背景執行)。 - 假設所有非同步程式碼都在背景執行(在 Swift 6.2 中,預設是留在原 Actor 執行的)。