3.0 KiB
3.0 KiB
| name | description |
|---|---|
| swift-concurrency-6-2 | 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 類型現在可以安全地順應非隔離的協定:
protocol Exportable {
func export()
}
// Swift 6.2:使用隔離性順應性,編譯器保證該協定內容僅在 MainActor 上執行
extension StickerModel: @MainActor Exportable {
func export() {
photoProcessor.exportAsPNG()
}
}
核心模式 2 — 顯式背景處理 @concurrent
當你真正需要平行處理效能時,顯式使用 @concurrent 標記將任務移交給併發線程池:
nonisolated final class PhotoProcessor {
// 顯式將耗時作業移至背景
@concurrent
static func extractSubject(from data: Data) async -> Sticker { /* 處理邏輯 ... */ }
}
// 調用者必須使用 await
let sticker = await PhotoProcessor.extractSubject(from: data)
遷移建議
- Xcode 設定:在 Build Settings 的 Swift Compiler -> Concurrency 區段啟用相關功能。
- 預設使用 MainActor:建議應用程式 Target 啟用「預設推斷 MainActor」模式,減少手動標記範本代碼。
- 優化熱點路徑:先進行測速效能分析 (Profile),僅針對真正的效能瓶頸(如圖片處理、大型計算)才掛上
@concurrent。
實踐之最佳實踐
- 從 MainActor 開始:優先撰寫單線程程式碼,優化留到最後。
- 僅針對運算密集型工作使用
@concurrent:如編碼、壓縮、複雜算法。 - 相信編譯器:如果編譯器報告資料競爭,則代表程式碼邏輯確實存在併發風險,請勿試圖使用
nonisolated掩蓋問題。
應避免的反模式
- 對每一個
async函式都標記@concurrent(大多數情況下並不需要背景執行)。 - 假設所有非同步程式碼都在背景執行(在 Swift 6.2 中,預設是留在原 Actor 執行的)。