Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 防止无Objective-C的NSKeyedArchiver引发异常_Swift_Nskeyedarchiver - Fatal编程技术网

Swift 防止无Objective-C的NSKeyedArchiver引发异常

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

在低于11的iOS版本上,抛出的
存档数据(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,但听起来我没有其他选择。谢谢你的评论:)好的-有了这些额外的信息,让我把评论变成一个答案。:)