claude-code/claude-zh/skills/swift-actor-persistence/SKILL.md

3.0 KiB
Raw Permalink Blame History

name description
swift-actor-persistence 在 Swift 中使用 Actors 進行線程安全的資料持久化 — 結合記憶體快取與檔案儲存,從設計上消除資料競爭 (Data Races)。

使用 Swift Actors 達成線程安全持久化

這是在 Swift 中使用 Actor 構建線程安全資料持久層的模式。它結合了記憶體快取 (In-memory cache) 與磁碟檔案存儲,利用 Actor 模型在編譯時期即消除資料競爭風險。

何時啟用

  • 在 Swift 5.5+ 環境下構建資料持久層。
  • 對共享的可變狀態 (Shared Mutable State) 需要線程安全存取。
  • 希望淘汰手動同步機制(如 Locks, DispatchQueue
  • 開發具備本地存儲能力的離線優先 (Offline-first) 應用程式。

核心模式:基於 Actor 的 Repository

Actor 模型保證了序列化存取 — 由編譯器強制執行單一時間點僅有一個任務能存取其內部狀態。

public actor LocalRepository<T: Codable & Identifiable> where T.ID == String {
    private var cache: [String: T] = [:]
    private let fileURL: URL

    public init(directory: URL = .documentsDirectory, filename: String = "data.json") {
        self.fileURL = directory.appendingPathComponent(filename)
        // 在 init 期間同步載入(此時 Actor Isolation 尚未啟用)
        self.cache = Self.loadSynchronously(from: fileURL)
    }

    // 提供給外部使用的線程安全 API
    public func save(_ item: T) throws {
        cache[item.id] = item
        try persistToFile()
    }

    public func find(by id: String) -> T? {
        cache[id]
    }

    // 私有實作:原子化寫入檔案以防止損毀
    private func persistToFile() throws {
        let data = try JSONEncoder().encode(Array(cache.values))
        try data.write(to: fileURL, options: .atomic)
    }
}

使用方式

由於 Actor 隔離機制,所有外部調用皆會自動轉換為 async 行為:

let repository = LocalRepository<User>()

// 讀取 — 從記憶體快取中進行極速 O(1) 查找
let user = await repository.find(by: "u-001")

// 寫入 — 同步更新快取並原子化持久化至磁碟
try await repository.save(newUser)

實踐之最佳實踐

  • 使用 Sendable 類型:確保所有跨越 Actor 邊界的資料皆符合 Sendable 協定。
  • 內部實作封裝Actor 的公開 API 應僅暴露業務邏輯操作,隱藏持久化細節。
  • 原子化寫入 (.atomic):防止 App 在寫入中途崩潰導致資料損毀。
  • 配合 @Observable:在 ViewModel 中使用,為 UI 提供反應式數據更新。

應避免的反模式

  • 在新的 Swift Concurrency 程式碼中繼續混用 DispatchQueueNSLock
  • 對外暴露內部的 Cache 字典。
  • 使用 nonisolated 關鍵字來規避 Actor 隔離(這會破壞線程安全性)。

適用情境

  • iOS/macOS 應用的本地資料存儲(用戶資料、偏好設定、快取內容)。
  • 需要更換舊有的 DispatchQueue 式同步邏輯,轉向現代化 Swift Concurrency 架構。