如何 NSKeyedUnarchiver.unarchiveObject

How to NSKeyedUnarchiver.unarchiveObject

我有一个有效但已弃用的工作代码:

这部分没问题:

 let archived = try? NSKeyedArchiver.archivedData(withRootObject: [defaultRecord] as NSArray, requiringSecureCoding: false)

已弃用:

 let records = NSKeyedUnarchiver.unarchiveObject(with: unarchivedObject as Data) as? [Record]

'unarchiveObject(with:)' was deprecated in iOS 12.0: Use +unarchivedObjectOfClass:fromData:error: instead

虽然听起来很简单,但我无法找到一种方法来使用建议的方法,而不会在我尝试的每个组合中出现错误。

有这方面的工作示例吗?

使用新的 API 来归档数组有点棘手。

如果您不忽略 try?

的错误,您本可以自己想出来的

为了能够使用 unarchivedObject(ofClass:from: 解码自定义 class 的数组,您必须使用 plural 形式 unarchivedObject(ofClasses:from: 并指定NSArray(!) 和自定义 class。此外,您的 class 必须采用 NSSecureCoding

class Record : NSObject, NSSecureCoding {

   static var supportsSecureCoding: Bool {
        return true
    }

....

do {
    let archived = try NSKeyedArchiver.archivedData(withRootObject: [defaultRecord], requiringSecureCoding: false)

    let records = try NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self, Record.self], from: archived) as! [Record]
    print(records)
} catch { print(error) }

但为什么要将 defaultRecord 存档为数组?如果您归档单个对象,您可以保留 class 原样并写入

do {
    let archived = try NSKeyedArchiver.archivedData(withRootObject: defaultRecord, requiringSecureCoding: false)

    let record = try NSKeyedUnarchiver.unarchivedObject(ofClass: Record.self, from: archived)
    let records = [record]
    print(records)
} catch { print(error) }

旁注:考虑将 class 序列化为 Codable。它 swiftier 并且不需要从 NSObject.

继承

上面的方法对我解压不起作用,我这样做了并且成功了:

NSKeyedUnarchiver.unarchivedObject(ofClasses: [Record.self], from: archived)

如果有人对 Objective C 代码感兴趣,请看这里:

// pointer to storage for error message
NSError *error = nil;

// read data from "dataPath" location
NSData *codedData = [[NSData alloc] initWithContentsOfFile:dataPath];

// create a set of root class (the array) and the data object class
NSSet<Class> *classes = [NSSet setWithObjects:NSArray.class, Record.class, nil];

// read using classes, not only single class
NSArray *data = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes fromData:codedData error:&error];

同样,这只是@vadian 正确指出的代码的“翻译”(救了我一命!)。