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

Swift 6中PreferenceKey数组类型defaultValue并发不安全如何解决?

Swift 6下PreferenceKey默认值的并发安全问题修复

首先看你定义的结构体代码:

struct DarkConnectorLineAnchor: Equatable {
    let anchor: Anchor<CGRect>
}
struct DarkStepPreferenceKey: PreferenceKey {
    static var defaultValue = [DarkConnectorLineAnchor]()
    static func reduce(
        value: inout [DarkConnectorLineAnchor],
        nextValue: () -> [DarkConnectorLineAnchor]
    ) {
        value.append(contentsOf: nextValue())
    }
}

在Swift 6语言模式下,这段代码会触发错误:

Static property 'defaultValue' is not concurrency-safe because it is nonisolated global shared mutable state

最优修复方案:将var改为let

你不需要把defaultValue声明为var,直接用let即可解决问题:

struct DarkStepPreferenceKey: PreferenceKey {
    static let defaultValue: [DarkConnectorLineAnchor] = []
    static func reduce(
        value: inout [DarkConnectorLineAnchor],
        nextValue: () -> [DarkConnectorLineAnchor]
    ) {
        value.append(contentsOf: nextValue())
    }
}

原因是:

  • Swift的数组是值类型,PreferenceKey的defaultValue仅用于提供初始空数组,后续所有状态修改都是在reduce方法中操作传入的inout value参数(这是方法内部的局部状态,不是全局共享的defaultValue)。
  • 全局静态var会被视为共享可变状态,违反Swift 6的并发安全规则;而let修饰的静态属性是不可变的天然线程安全,完全符合要求。

其他备选方案(仅当确实需要可变defaultValue时)

如果你的业务场景真的需要defaultValue是可变的(这种情况在PreferenceKey的使用中非常罕见),可以通过actor隔离来修复:

@MainActor
struct DarkStepPreferenceKey: PreferenceKey {
    static var defaultValue = [DarkConnectorLineAnchor]()
    static func reduce(
        value: inout [DarkConnectorLineAnchor],
        nextValue: () -> [DarkConnectorLineAnchor]
    ) {
        value.append(contentsOf: nextValue())
    }
}

但这种方案没必要,因为defaultValue在PreferenceKey的设计中只需要提供初始值,不需要被外部修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 02:31:08