``cannotDecodeObjectOfClassName``不在'NSKeyedArchiverDelegate`中调用
我试图捕获NSKeyedUnarchiver
取消存档异常NSInvalidUnarchiveOperationException
,其中未知类正在通过NSSecureCoding
协议安全解码。``cannotDecodeObjectOfClassName``不在'NSKeyedArchiverDelegate`中调用
我使用的解决方案基于相关的NSKeyedUnarchiverDelegate SO post,通过实施代理协议NSKeyedUnarchiverDelegate
,因此我可以通过unarchiver(_:cannotDecodeObjectOfClassName:originalClasses:)
收听和回应异常。但是,在解码过程中遇到未知类时,该委托方法似乎不会被调用。
下面是我用于安全地取消存档数组对象的代码片段。
func securelyUnarchiveArrayOfCustomObject(from url: URL, for key: String) -> [MyCustomClass]? {
guard let data = try? Data(contentsOf: url) else {
os_log("Unable to locate data at given url.path: %@", log: OSLog.default, type: .error, url.path)
return nil
}
let unarchiver = NSKeyedUnarchiver(forReadingWith: data)
let delegate = UnarchiverDelegate() // Prevents `NSInvalidUnarchiveOperationException` crash
unarchiver.delegate = delegate
unarchiver.requiresSecureCoding = true // Prevents object substitution attack
let allowedClasses = [NSArray.self] // Will decode without problem if using [NSArray.self, MyCustomClass.self]
let decodedObject = unarchiver.decodeObject(of: allowedClasses, forKey: key)
let images = decodedObject as! [ImageWithCaption]?
unarchiver.finishDecoding()
return images
}
在我的UnarchiverDelegate
在原始NSKeyedUnarchiverDelegate SO post实现就像我指了指。在我的设置,decodeObject(of: allowedClasses, forKey: key)
不会抛出一个异常,而是提出了一个运行时异常:
'NSInvalidUnarchiveOperationException', reason:
'value for key 'NS.objects' was of unexpected class
'MyCustomClassProject.MyCustomClass'. Allowed classes are '{(
NSArray
)}'.'
推测这是刚才那种例外的是NSKeyedUnarchiverDelegate
的unarchiver(_:cannotDecodeObjectOfClassName:originalClasses:)
应该被调用,基于its documentation:
通知代表具有给定名称的类在解码期间不可用。
但在我的情况下,该方法不与上述代码段调用(即使其它委托方法,像unarchiverWillFinish(_:)
或unarchiver(_:didDecode:)
通常调用时解码不会遇到的问题。
不同于在原文中,我不能使用像decodeTopLevelObjectForKey
这样的类函数,在那里我可以用try?
来处理异常,因为我需要支持使用NSSecureCoding
协议的安全编码和解码,像讨论的here一样,这迫使我使用decodeObject(of:forKey)
,它不会抛出我可以处理的任何异常,并且,在抛出导致应用程序崩溃的运行时异常之前,它不会通知我的委托人。
实际调用委托方法unarchiver(_:cannotDecodeObjectOfClassName:originalClasses:)
的场景是什么?我如何聆听并响应我的NSSecureCoding
设置下的NSInvalidUnarchiveOperationException
,以便在解码不成功时避免运行时崩溃?