You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift6:创建符合Sendable协议的类时可变存储属性报错求解决

解决Sendable协议类中可变数组的报错问题

报错的核心原因是:遵循Sendable协议的类,其可变存储属性必须保证线程安全。普通的var counters: [Int]是可变的非线程安全属性,编译器无法确保多线程环境下的访问安全,因此触发错误。

以下是三种可行的解决方法:

方案一:改用Actor(Swift并发最佳实践)

Actor是Swift并发模型中专门用于线程安全状态管理的类型,天然遵循Sendable,内部状态会被自动保护,无需额外声明协议。

@Observable actor Manager {
    var hasContent: Bool {
        return counters.count > 0
    }
    private var counters: [Int] = []
    
    func lastNumber() -> Int? {
        return counters.last
    }
    
    func addCounter() {
        let number = Int.random(in: 1...50)
        counters.append(number)
    }
}

适用场景:需要在多线程环境下安全修改状态的业务逻辑。

方案二:用@MainActor限制所有操作到主线程

如果你的Manager仅在主线程中使用,给类添加@MainActor标记,强制所有属性访问和方法调用都在主线程执行,避免多线程竞争。

@Observable @MainActor final class Manager: Sendable {
    var hasContent: Bool {
        return counters.count > 0
    }
    private var counters: [Int] = []
    
    func lastNumber() -> Int? {
        return counters.last
    }
    
    func addCounter() {
        let number = Int.random(in: 1...50)
        counters.append(number)
    }
}

适用场景:UI相关的状态管理,所有操作天然绑定主线程。

方案三:手动用线程锁保护可变属性

如果必须使用普通类且需要支持多线程修改,可通过锁(如NSLock)包裹对counters的所有读写操作,确保同一时间只有一个线程访问该属性。

@Observable final class Manager: Sendable {
    var hasContent: Bool {
        lock.lock()
        defer { lock.unlock() }
        return counters.count > 0
    }
    private var counters: [Int] = []
    private let lock = NSLock()
    
    func lastNumber() -> Int? {
        lock.lock()
        defer { lock.unlock() }
        return counters.last
    }
    
    func addCounter() {
        let number = Int.random(in: 1...50)
        lock.lock()
        defer { lock.unlock() }
        counters.append(number)
    }
}

适用场景:需要兼容旧代码或特殊线程模型的场景,但需确保所有读写操作都经过锁保护,避免遗漏导致数据竞争。

内容的提问来源于stack exchange,提问作者reza23

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 20:12:45