使用NSSecureCoding时多次解码同一对象失败的疑问
关于NSSecureCoding解码时NSCoder行为的疑问
使用NSSecureCoding进行对象编解码操作时,测试多种解归档方式发现,移除部分打印语句会改变解码器的行为。想问:当对象被解码后,NSCoder对象是否会失效?这是预期行为吗?
测试前
假设FakeObject存储在"FakeObjectKey"键下,尝试三种不同方式解码并打印输出,代码如下:
print("FakeObject exists? \(coder.containsValue(forKey: "FakeObjectKey"))") print("FakeObject insecure? \(coder.decodeObject(forKey: "FakeObjectKey"))") print("FakeObject secure? \(coder.decodeObject(of: FakeObject.self, forKey: "FakeObjectKey"))")
输出显示检测到对象存在,但后两次解码均返回nil:
FakeStorekeeper exists? true FakeStorekeeper insecure? nil FakeStorekeeper secure? nil
测试后
注释前两行打印语句后,第三种解码方式成功执行,代码如下:
// print("FakeObject exists? \(coder.containsValue(forKey: "FakeObjectKey"))") // print("FakeObject insecure? \(coder.decodeObject(forKey: "FakeObjectKey"))") print("FakeObject secure? \(coder.decodeObject(of: FakeObject.self, forKey: "FakeObjectKey"))")
输出变为:
FakeObject secure? Optional(< FakeObject: 0x60000022a180>)
问题解答
- NSCoder对象本身不会在解码后失效,但单个key对应的数据只能被解码一次——这是NSCoder的预期行为。
- 归档流是单向读取的,当你调用
decodeObject(forKey:)(无论安全或不安全版本)时,解码器会读取并消耗该key对应的数据。后续再针对同一个key调用解码方法,就会返回nil,因为数据已经被读取完毕。 - 测试前的代码中,先调用了不安全的
decodeObject(forKey:),已经消耗了"FakeObjectKey"对应的数据,所以后续的安全解码方法无法获取到数据,返回nil。 containsValue(forKey:)方法仅检查key是否存在,不会消耗数据,所以它的调用不影响后续解码,但前面的不安全解码操作已经把数据用掉了。- 注释前两行后,第一次调用的是安全解码方法,此时对应key的数据还未被消耗,因此可以成功解码出对象。
内容的提问来源于stack exchange,提问作者Warpling
相关产品推荐
相关产品推荐

