Swift 6语言模式下SwiftData #Predicate的Sendable协议兼容问题咨询
Swift 6语言模式下SwiftData #Predicate的Sendable协议兼容问题咨询
嘿,这个问题我在迁移自己的SwiftData项目到Swift 6的时候也碰到过,简直一模一样!我来给你捋清楚怎么解决。
首先说问题出在哪:Swift 6开启严格并发模式后,编译器会强制要求所有可能在并发上下文中传递的类型都得遵循Sendable协议。你看到的警告指向\.archived这个KeyPath,是因为ReferenceWritableKeyPath<Rubric, Bool>这个类型的Sendable一致性,完全依赖于根类型Rubric和值类型Bool是否符合Sendable——Bool是值类型天然没问题,但你的Rubric类只加了@Model、Identifiable和Comparable,没显式声明遵循Sendable,导致这个KeyPath类型过不了编译器的Sendable检查,刚好#Predicate的宏展开代码把这个问题暴露出来了。
解决方法其实很简单,就一步:
- 给你的
Rubric模型类显式加上Sendable协议遵循
别担心,SwiftData的@Model宏生成的底层实现本来就是支持并发安全的,只是默认没把Sendable写在声明里而已。修改后的类声明应该是这样:@Model class Rubric: Identifiable, Comparable, Sendable { init() { ... } var subject: String = "" var unit: String = "" var archived: Bool = false // 你原来的其他属性和方法 }
改完之后,你原来的notArchived()方法完全不用动:
static func notArchived() -> Predicate<Rubric> { return #Predicate<Rubric> { rubric in !rubric.archived } }
编译器的警告应该就直接消失了。
额外提一句:如果你的Rubric里有自定义的非Sendable类型的属性(比如自己写的没遵循Sendable的类),那你得先把那些属性改成Sendable兼容的——要么让那个自定义类遵循Sendable,要么换成值类型,或者用@Sendable包装。不过从你给出的代码来看,现有的属性都是String、Bool这种天然符合Sendable的类型,所以直接加个协议遵循就搞定了。
内容来源于stack exchange
相关产品推荐
相关产品推荐

