【问题标题】:Resolving `+[NSKeyedUnarchiver unarchiveTopLevelObjectWithData:error:]` deprecation leads to 'data couldn’t be read' error解决 `+[NSKeyedUnarchiver unarchiveTopLevelObjectWithData:error:]` 弃用导致“无法读取数据”错误
【发布时间】:2020-01-14 21:49:49
【问题描述】:

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

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];

...失败并出现以下错误:

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

如何用非弃用方法正确替换这种弃用方法?

【问题讨论】:

    标签: objective-c nscoding


    【解决方案1】:

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

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

    重要
    确保您在解码的类型中采用了 NSSecureCoding。如果对 decode-prefixed 方法的任何调用失败,默认的decodeFailurePolicy 会设置错误而不是抛出异常。在这种情况下,当前和所有后续的解码调用都返回 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. (可选)将您的编码调用更改为要求安全编码(即第二个参数可以是YES):

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

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

    【讨论】:

    • 已经搜索了一段时间,这是我找到的第一个可理解的答案。非常感谢,人!
    猜你喜欢
    • 2016-08-07
    • 1970-01-01
    • 1970-01-01
    • 2018-08-03
    • 2023-03-24
    • 2023-03-27
    • 2014-02-13
    • 1970-01-01
    • 2022-10-07
    相关资源
    最近更新 更多