Core Data存储Measurement时安全编码NSValueTransformer配置崩溃
你遇到的134060错误是Core Data持久化可转换属性时,安全编码校验失败触发的保存/读取回滚,核心踩了两个隐蔽的配置坑:
- 自定义Transformer的允许类列表配置不全:你当前实现的
allowedTopLevelClasses只返回了UnitLength.self,但实际存储的顶层归档对象是SwiftMeasurement<UnitLength>对应的Objective-C桥接类NSMeasurement,UnitLength只是NSMeasurement内部持有的嵌套属性。按照NSSecureUnarchiveFromDataTransformer的校验规则,只要归档的类不在允许列表内,就会直接抛出解码失败,导致整个Core Data保存操作回滚。 - 模型配置和自定义Transformer未绑定:哪怕Transformer代码写对了,如果在
.xcdatamodeld文件里没有给length_属性正确配置关联的Transformer名称,Core Data会调用默认的序列化逻辑,因为默认逻辑的允许类列表不包含NSMeasurement,同样会触发安全校验失败。
修正Transformer的允许类配置
调整UnitLengthValueTransformer的allowedTopLevelClasses返回值,把归档过程涉及的所有类加入允许列表,避免安全校验拦截:override static var allowedTopLevelClasses: [AnyClass] { return [NSMeasurement.self, UnitLength.self] }不需要额外实现归档/解档逻辑,
NSSecureUnarchiveFromDataTransformer的父类已经处理了通用的NSKeyedArchiver编码流程,只需要把需要允许的类列全即可。核对Core Data模型的匹配配置
打开.xcdatamodeld文件选中Item实体下的length_可转换属性,确认三个配置项:- 开启
Use Scalable Format选项,这是Core Data兼容安全编码存储的核心开关 - 在
Value Transformer输入框中,填入和代码中Transformer名完全一致的字符串:UnitLengthValueTransformer(和你代码里String(describing: UnitLengthValueTransformer.self)生成的命名匹配,不要混用系统默认的Transformer名称) - 确认属性类型为
Transformable
- 开启
保证Transformer注册顺序正确
你当前在Appinit方法里先执行UnitLengthValueTransformer.register()、再初始化PersistenceController的顺序是正确的,不需要调整——只要保证Transformer在Core Data加载持久化存储、首次执行持久化操作之前完成注册,就不会出现“找不到对应Transformer”的问题。
注意:如果修改配置后首次启动仍触发崩溃,是因为沙盒中残留了之前未按安全格式存储的旧数据,删除App重装即可清除旧存储文件。
Xcode默认的Core Data模板在保存失败时的错误打印会丢失详细的错误上下文,只输出模糊的134060错误。你可以在崩溃的保存逻辑位置,把完整的NSError信息打印出来,就能看到具体是哪个类触发了安全校验拦截:
do { try context.save() } catch { let nsError = error as NSError // 打印完整错误的domain、code、userInfo,定位具体拦截原因 NSLog(@"Core Data 错误详情: %@", nsError) fatalError("Unresolved error \(nsError), \(nsError.userInfo)") }
内容的提问来源于stack exchange,提问作者Yrb

