替换废弃NSKeyedUnarchiver方法失败,仅支持单对象,求解决方案
NSKeyedArchiver/Unarchiver废弃方法替换踩坑解决
问题本质
你用旧API归档的数组数据,直接用unarchivedArrayOfObjects(ofClass:from:)解档失败,核心原因是新旧API的归档格式不兼容:旧方法是将整个Swift数组桥接为NSArray后作为根对象归档,而新的解档方法要求数据是用对应新归档逻辑生成的,且对数组内对象的NSSecureCoding实现有严格要求。
前提检查:确保CustomClass合规
首先必须保证CustomClass正确实现NSSecureCoding协议,这是所有新归档API的硬性要求:
class CustomClass: NSObject, NSSecureCoding { // 必须实现这个静态属性,返回true static var supportsSecureCoding: Bool { true } // 你的自定义属性 var name: String? // 编码逻辑 func encode(with coder: NSCoder) { coder.encode(name, forKey: "name") } // 解码逻辑 required init?(coder: NSCoder) { name = coder.decodeObject(forKey: "name") as? String super.init() } }
分场景解决方案
场景1:全新归档/解档(无历史数据)
直接替换成对的新API,保持归档和解档逻辑一致:
- 归档代码:
// 将Swift数组桥接为NSArray后归档,确保符合SecureCoding要求 let data = try NSKeyedArchiver.archivedData(withRootObject: tabCustomObj as NSArray, requiringSecureCoding: true)
- 解档代码:
// 直接用数组专属解档方法,严格校验内部对象类型 let restoredArray = try NSKeyedUnarchiver.unarchivedArrayOfObjects(ofClass: CustomClass.self, from: data)
场景2:需要兼容历史归档数据
如果已经有旧方法生成的历史数据,需要先兼容解档,再转存为新格式:
// 先用旧方法解档历史数据 guard let oldArray = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? [CustomClass] else { // 解档失败处理 return } // 转存为新格式的数据,后续即可用新API解档 let newData = try NSKeyedArchiver.archivedData(withRootObject: oldArray as NSArray, requiringSecureCoding: true) // 将newData保存到本地覆盖旧数据
场景3:临时兼容解档(不想立即转存)
如果暂时不想转存历史数据,也可以用通用解档方法先获取数组,再做类型转换:
let restoredArray = try NSKeyedUnarchiver.unarchivedObject(ofClass: NSArray.self, from: data) as? [CustomClass]
为什么你的尝试会失败
unarchivedArrayOfObjects(ofClass:from:)是专门针对用新归档逻辑生成的数组数据设计的,它会严格校验归档数据的内部结构是否符合数组对象的SecureCoding编码规范。而旧方法归档的数组,底层编码结构是根对象为NSArray的通用归档格式,和新方法的预期不匹配,因此会解档失败。
内容的提问来源于stack exchange,提问作者ek88
相关产品推荐
相关产品推荐

