Swift 防止无Objective-C的NSKeyedArchiver引发异常
在低于11的iOS版本上,抛出的Swift 防止无Objective-C的NSKeyedArchiver引发异常,swift,nskeyedarchiver,Swift,Nskeyedarchiver,在低于11的iOS版本上,抛出的存档数据(withRootObject:RequiringSecureCodeding:)不可用,因此我尝试在低于iOS 11的版本上执行等效操作: let archiveData:NSData 如果可用(iOS 11.0,*){ archiveData=尝试NSKeyedArchiver.archivedData( withRootObject:rootObject, RequiringSecureCodeding:true )作为NSData }否则{ NSK
存档数据(withRootObject:RequiringSecureCodeding:)
不可用,因此我尝试在低于iOS 11的版本上执行等效操作:
let archiveData:NSData
如果可用(iOS 11.0,*){
archiveData=尝试NSKeyedArchiver.archivedData(
withRootObject:rootObject,
RequiringSecureCodeding:true
)作为NSData
}否则{
NSKeyedArchiver.archivedData(withRootObject:userActivity)
设mutableData=NSMutableData()
让archiver=NSKeyedArchiver(用于写入:可变数据)
archiver.requirescurecoding=true
encode(rootObject,forKey:NSKeyedArchiveRootObjectKey)
如果let error=archiver.error{
抛出错误
}
archiver.finishEncoding()
archiveData=可变数据
}
但是,当rootObject
调用encode(with:)
函数中的NSCoder.failWithError(:)
时,会引发NSInvalidUnarchiveOperationException
异常
如果我将NSKeyedArchiver
子类化为:
final类KeyedArchiver:NSKeyedArchiver{
覆盖var decodingFailurePolicy:NSCoder.decodingFailurePolicy{
return.setErrorAndReturn
}
}
相反,它会引发一个nsinternalinconsistenceexception
异常,消息是试图在抛出NSCoder时设置解码错误
除了编写Objective-C函数捕获异常并将其作为错误抛出之外,有没有一种方法可以在不引发异常的情况下进行此类归档?在编码时仍会出现异常的原因是.decodingFailurePolicy
仅在解码时有效(即,通过NSKeyedUnarchiver
)取消归档),不进行编码。在编码时调用.failWithError(:)
的任何对象仍将产生异常
在编码时调用.failWithError(:)
相对较少:通常,一旦在运行时拥有一个完全构造的对象,它不太可能处于不可编码的状态。当然,在某些情况下,这是可能的,因此您确实有两种选择:
如果您正在处理您知道的对象,并且可以提前检查它们是否处于可编码的有效状态,那么您应该这样做,并避免对无效对象进行编码
如果您使用的是无法预先验证的任意对象,则必须通过Objective-C函数将调用包装到NSKeyedArchiver
,该函数可以捕获异常(理想情况下,抛出包含该异常的错误
,就像较新的NSKeyedArchiver
API代表您所做的那样)
根据你上面的评论,选择2是你最好的选择
另外,您可以缩短回退代码,以避免构建中间NSMutableData
实例:
let archiver=NSKeyedArchiver()
encode(rootObject,forKey:NSKeyedArchiveRootObjectKey)
archiveData=archiver.encodedData
NSKeyedArchiver
上的默认初始值设定项使用内部可变数据实例构造一个新的archiver,并且NSKeyedArchiver.encodedData
属性自动代表您调用-finishEncoding
。解码失败策略仅在解码时有效(通过NSKeyedUnarchiver
取消归档),而不是编码。rootObject
产生的错误是什么?为什么?如果可以提前检测到错误,最好的避免方法就是不要尝试编码-否则,您可能需要捕获Obj-C中的异常。这是有意义的,我没有发现这是解码策略!此代码用于开源框架,所以我不知道rootObject
是否会产生错误,所以我希望在11.0之前的iOS版本上尽可能安全。我希望我不必使用Obj-C,但听起来我没有其他选择。谢谢你的评论:)好的-有了这些额外的信息,让我把评论变成一个答案。:)