SwiftData使用Measurement<UnitType>模拟器崩溃,请求排查问题原因
SwiftData使用Measurement类型运行崩溃问题解决
问题结论
这是SwiftData在Xcode 15 beta 8及RC版本中的未修复限制(可视为bug),当前SwiftData不支持直接将Measurement类型作为@Model的存储属性。
崩溃原因
SwiftData的Schema解析逻辑无法正确处理Measurement这类包含复合结构的类型(内部包含数值和NSUnit子类实例),运行时尝试解析NSUnitLength时触发断言错误,导致崩溃。
临时解决方案
目前只能通过间接方式存储Measurement数据,推荐两种可行方案:
方案1:拆分属性存储
将Measurement拆分为数值和单位符号两个基础属性,通过计算属性对外暴露Measurement类型:
import Foundation import SwiftData @Model final class Item { var lengthValue: Double var lengthUnit: String // 对外提供的Measurement计算属性 var length: Measurement<UnitLength> { get { guard let unit = UnitLength(symbol: lengthUnit) else { return Measurement(value: 0, unit: .meters) } return Measurement(value: lengthValue, unit: unit) } set { lengthValue = newValue.value lengthUnit = newValue.unit.symbol } } init(length: Measurement<UnitLength>) { self.lengthValue = length.value self.lengthUnit = length.unit.symbol } }
方案2:编码为Data存储
将Measurement编码为Data类型存储,通过计算属性完成编解码转换:
import Foundation import SwiftData @Model final class Item { var lengthData: Data var length: Measurement<UnitLength> { get { guard let measurement = try? JSONDecoder().decode(Measurement<UnitLength>.self, from: lengthData) else { return Measurement(value: 0, unit: .meters) } return measurement } set { if let data = try? JSONEncoder().encode(newValue) { lengthData = data } } } init(length: Measurement<UnitLength>) { self.lengthData = (try? JSONEncoder().encode(length)) ?? Data() } }
后续建议
- 关注Xcode 15正式版及后续更新的发布说明,确认官方是否添加了
Measurement类型的直接支持 - 若需反馈问题,可通过Apple开发者渠道提交Bug报告
内容的提问来源于stack exchange,提问作者0x1801ce
相关产品推荐
相关产品推荐

