使用 NSKeyedUnarchiver 解码 URL 对象数组

Posted

技术标签:

【中文标题】使用 NSKeyedUnarchiver 解码 URL 对象数组【英文标题】:Decoding array of URL objects using NSKeyedUnarchiver 【发布时间】:2020-03-20 01:59:35 【问题描述】:

我正在尝试。代码如下:

let urlArray: [URL] = [URL(string: "https://apple.com")!,
                       URL(string: "https://google.com")!]

do 
    let archivedUrls = try NSKeyedArchiver.archivedData(withRootObject: urlArray, requiringSecureCoding: false)
    let _ = try NSKeyedUnarchiver.unarchivedObject(ofClass: NSArray.self, from: archivedUrls)
 catch 
    print(error)

我收到以下错误:

Error Domain=NSCocoaErrorDomain Code=4864 "value for key 'NS.objects' was of unexpected class 'NSURL'. Allowed classes are '(
    NSArray
)'." UserInfo=NSDebugDescription=value for key 'NS.objects' was of unexpected class 'NSURL'. Allowed classes are '(
    NSArray
)'.

如果我用let _ = try NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self, NSURL.self], from: archivedUrls) 替换let _ = try NSKeyedUnarchiver.unarchivedObject(ofClass: NSArray.self, from: archivedUrls),那么它可以工作。但这意味着它可以解码NSArrayNSURL 对象,而不是包含NSURL 对象的NSArray

如果我将数组更改为 String 的数组,则一切正常:

let stringArray: [String] = ["string", "string2"]

do 
    let archivedStrings = try NSKeyedArchiver.archivedData(withRootObject: stringArray, requiringSecureCoding: false)
    let _ = try NSKeyedUnarchiver.unarchivedObject(ofClass: NSArray.self, from: archivedStrings)
 catch 
    print(error)

有人对这种行为有解释吗?

【问题讨论】:

【参考方案1】:

如果您不需要安全编码 (requiringSecureCoding: false),您可以使用 unarchiveTopLevelObjectWithData(_:)

do 
    let archivedUrls = try NSKeyedArchiver.archivedData(withRootObject: urlArray, requiringSecureCoding: false)
    if let urls = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(archivedUrls) as? [URL] 
        print(urls)
     else 
        print("not URLs")
    
 catch 
    print(error)

或者您可以使用unarchivedObject(ofClasses:from:) 指定存档中包含的类型。

do 
    let archivedUrls = try NSKeyedArchiver.archivedData(withRootObject: urlArray, requiringSecureCoding: true)
    if let urls = try NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self, NSURL.self], from: archivedUrls) as? [URL] 
        print(urls)
     else 
        print("not URLs")
    
 catch 
    print(error)

NSString 似乎是这条规则的一个例外。

【讨论】:

以上是关于使用 NSKeyedUnarchiver 解码 URL 对象数组的主要内容,如果未能解决你的问题,请参考以下文章

-[NSKeyedUnarchiver decodeObjectForKey:]:无法解码类的对象

NSKeyedUnarchiver decodeObjectForKey:无法解码类对象的键(NS.objects)

如何将代表与 NSKeyedUnarchiver 一起使用?

错误处理 - NSKeyedUnarchiver

NSKeyedUnarchiver 数据格式错误

iPhone - NSKeyedUnarchiver 内存泄漏