解决 '+[NSKeyedUnarchiver unarchiveTopLevelObjectWithData:error:]' 弃用会导致'data couldn’t be read'错误



我有这段代码,它可以工作:

Foo *foo = [NSKeyedUnarchiver unarchiveTopLevelObjectWithData:data error:&error];

但是,它给了我这个警告:

'unarchiveTopLevelObjectWithData:error:' 已弃用:在 iOS 12.0 中首次弃用 - 使用 +unarchivedObjectOfClass:fromData:error: 代替

当我尝试用以下方法进行简单的替换时:

Foo *foo = [NSKeyedUnarchiver unarchivedObjectOfClass:[Foo class] fromData:data error:&error];

。它失败并显示以下错误:

无法读取数据,因为它的格式不正确。

如何将此已弃用的方法正确替换为未弃用的方法?

这可能是因为你的对象符合NSCoding,但它应该符合NSSecureCoding

如果您查看unarchivedObjectOfClass:fromData:error:的文档,您会注意到它说:

重要说明
请确保已在解码的类型中采用 NSSecureCoding 。如果对以解码为前缀的方法的任何调用失败,则默认的解码失败策略将设置错误,而不是引发异常。在这种情况下,当前和所有后续解码调用返回 0 或 nil。

因此,您需要执行以下操作才能切换到未弃用的函数:

  1. 将函数从[NSKeyedUnarchiver unarchiveTopLevelObjectWithData:data error:&error]切换到[NSKeyedUnarchiver unarchivedObjectOfClass:[Foo class] fromData:data error:&error],如弃用警告所述。
  2. 支持安全编码:

    1. 将顶级对象的一致性从NSCoding切换到NSSecureCoding
    2. 添加属性:

      @property (class, readonly) BOOL supportsSecureCoding;
      
    3. 实现方法:

      + (BOOL)supportsSecureCoding {
      return YES;
      }
      
    4. 如果您的对象具有任何其他属性NSCoding请对它们重复所有这些步骤,以便它们最终符合NSSecureCoding。 例如,如果正在编码的Foo对象上存在属性@property (nonatomic, strong) Bar *bar;,则需要确保Bar也符合NSSecureCoding,而不仅仅是NSCoding

  3. (
  4. 可选(将编码调用更改为需要安全编码(即可以YES第二个参数(:

    [NSKeyedArchiver archivedDataWithRootObject:self requiringSecureCoding:YES error:&error];
    

苹果似乎希望人们从NSCoding切换到NSSecureCoding,如果NSCoding也被弃用,上面的问题会更明显地解决。

相关内容

最新更新