使用NSKeyedUnarchiver

时间:2017-08-11 11:29:41

标签: swift cocoa-touch nscoding nskeyedarchiver nskeyedunarchiver

我们有一个Swift类,它继承自NSObject并实现了NSCoding。我们需要在磁盘上的存档中更改代码中的类名称。幸运的是,我们不需要保留数据。擦除缓存的文件并返回默认数据就可以了。问题在于检测何时失败并适当地处理它。

好的,首先要写出这样的数据(忽略自由力量展开等等,这只是为了让问题简明扼要):

let someObject: [Int: MyClass] = ...
let data = NSKeyedArchiver.archivedData(withRootObject: someObject)
try! data.write(to: someUrl, options: .atomic)

这很好用。我们现有的解码方法就是这样(同样,我们的代码在实践中更安全):

let someObject = NSKeyedUnarchiver.unarchiveObject(withFile: someUrl.path)! as! [Int: MyClass]

现在,当我们重命名我们的类时,我们将不得不处理它无法解码的情况。使用NSKeyedUnarchiver,您可以设置一个委托,如果解码失败,该委托将调用一个方法。在更改之前,我想重新编写现有的解码器,以确保在进行任何更改之前可以解码。不幸的是,它不能。这是我们得到的:

let fileData = fileManager.contents(atPath: fileUrl.path)!
let unarchiver = NSKeyedUnarchiver(forReadingWith: fileData)
guard let myObject = try! unarchiver.decodeTopLevelObject() as? [Int: MyClass] else {
  return [Int: MyClass]()
}

现在,我没想到会遇到任何问题。但是,对decodetopLevelObject()的调用每次都会失败,只需返回nil(这绝对不是演员问题)。我不知道为什么。这方面的文档实际上是不存在的。有一个类似的调用是decodeObject(),但这也没有明显的原因。我已经尝试过设置委托并实现该方法,但它永远不会被调用。

我们哪里出错了?

1 个答案:

答案 0 :(得分:0)

尝试将decodeObject(forKey:)NSKeyedArchiveRootObjectKey或类似的API结合使用。