SwiftData使用带关联值的枚举属性时崩溃问题求助
SwiftData带关联值枚举崩溃问题解决
注意:此问题已在Xcode 15 RC版本中解决。除非您因特殊原因仍在使用Xcode 15测试版,否则这并非您需要关注的问题。
核心结论
SwiftData完全支持带关联值的枚举,你遇到的崩溃是Xcode 15 beta 3版本中的框架实现bug,和你的代码逻辑无关。
解决方案
1. 最优方案:升级Xcode版本
直接升级到Xcode 15 RC或后续正式版,苹果已经在该版本中修复了SwiftData处理带关联值枚举的解码逻辑错误,升级后你的原始代码即可正常运行。
2. 临时兼容方案(无法升级时)
如果暂时无法升级测试版,可以通过以下两种方式绕过bug:
- 方式一:标记为临时属性
给枚举属性添加@Transient注解,将其排除在SwiftData持久化体系外,但该属性不会被存储到数据库中:@Model final class Something { var name: String @Transient var thing: Something.Whatever // 添加@Transient init() { self.name = "" self.thing = .a } enum Whatever: Codable, Hashable { case a case b(Int) } } - 方式二:拆分枚举与关联值
将枚举的case类型和关联值拆分为两个独立的模型属性,通过计算属性模拟原枚举的行为:@Model final class Something { var name: String var thingCase: ThingCase var thingAssociatedValue: Int? init() { self.name = "" self.thingCase = .a self.thingAssociatedValue = nil } // 模拟原枚举的计算属性 var thing: Whatever { get { switch thingCase { case .a: return .a case .b: return .b(thingAssociatedValue ?? 0) } } set { switch newValue { case .a: thingCase = .a thingAssociatedValue = nil case .b(let value): thingCase = .b thingAssociatedValue = value } } } enum ThingCase: Codable, Hashable { case a, b } enum Whatever: Codable, Hashable { case a case b(Int) } }
崩溃原因说明
崩溃发生在SwiftData自动生成的属性getter中,底层try!表达式解码枚举时抛出错误:
SwiftData/BackingData.swift:211: Fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.typeMismatch(..., debugDescription: "Invalid number of keys found, expected one.")
这是因为测试版中SwiftData对带关联值枚举的解码逻辑存在缺陷,无法正确识别枚举的结构,该问题已在Xcode 15 RC中被修复。
内容的提问来源于stack exchange,提问作者HangarRash
相关产品推荐
相关产品推荐

