You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

替换废弃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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 21:37:43