如何用@Entry宏创建兼容SwiftData PersistentModel的自定义环境值?
问题场景
我们有一个简单的SwiftData模型:
import Foundation import SwiftData @Model final class Item { var timestamp: Date init(timestamp: Date) { self.timestamp = timestamp } }
尝试用SwiftUI新的@Entry宏为EnvironmentValues添加支持Item?类型的环境键时,触发构建错误:
import SwiftUI import SwiftData extension EnvironmentValues { @Entry var someItem: Item? = nil }
错误提示:
Static property 'defaultValue' is not concurrency-safe because non-'Sendable' type 'EnvironmentValues.__Key_someItem.Value' (aka 'Optional
- ') may have shared mutable state
测试环境:Xcode 16.0 beta (16A5171c) / Swift 6 / iOS 18
解决方案
原因分析
Swift 6默认启用严格并发检查,@Entry宏生成的EnvironmentKey要求关联的值类型必须遵守Sendable协议,以保证并发环境下的安全性。但默认的@Model类并没有自动遵守Sendable,导致Optional<Item>不符合要求,触发错误。
修复步骤
只需让你的SwiftData模型类显式遵守Sendable协议即可——SwiftData内部已经保证了模型实例的线程安全访问,添加该协议是安全的:
修改后的Item模型代码:
import Foundation import SwiftData @Model final class Item: Sendable { var timestamp: Date init(timestamp: Date) { self.timestamp = timestamp } }
此时再运行之前的EnvironmentValues扩展代码,构建错误就会消失。
补充说明
如果你的模型包含自定义可变属性,只要这些属性的类型本身是Sendable(比如Date、String、Int等基础类型),添加Sendable协议就不会有问题。SwiftData会负责处理模型实例的线程同步,无需额外手动管理。
内容的提问来源于stack exchange,提问作者parapote

