【问题标题】:Using decodeObject(of: forKey:) to decode an object that conforms to a protocol使用 decodeObject(of: forKey:) 解码符合协议的对象
【发布时间】:2018-06-07 21:52:42
【问题描述】:

我有一个需要符合 NSSecureCoding 的 Objective-C 协议:

@protocol MyProtocol <NSObject, NSSecureCoding>
…
@end

我有一个父对象,它存储对符合MyProtocol 的对象的引用,并且我希望父对象也符合NSSecureCoding。当我尝试这个时:

required init?(coder aDecoder: NSCoder) {

    if let childObject = aDecoder.decodeObject(of: MyProtocol.self, forKey: "childObject") {
        self. childObject = childObject
    } else {
        return nil
    }
}

我收到错误:'decodeObject(of:forKey:)' is unavailable in Swift: use generic 'decodeObjectOfClass(_:forKey:)'

如果你不知道你编码的对象的具体类,有什么方法可以使用 NSSecureCoding?

【问题讨论】:

    标签: ios swift protocols nssecurecoding


    【解决方案1】:

    NSSecureCoding 的全部意义在于防止这种用例。如果您不知道要解码的类,那么攻击者可以诱使您解码为与给定方法所期望的行为不同的类(称为“替代攻击”)。这是一种用于攻击系统的技术,NSSecureCoding 就是为了阻止它而开发的。

    即使不是这样,也不可能构造协议类型的对象。运行时无法知道要为实例变量分配多少内存。

    为了符合NSSecureCoding,你必须知道所有子对象的精确类。

    【讨论】:

    • 我想我听说 NSCoding 将被弃用,转而支持 NSSecureCoding,在不久的将来我刚刚观看的 WWDC 会议之一。如果属实,在这种情况下我该怎么办?
    • @JeffV 这不是真的:无意弃用NSCoding。您可以在取消归档时禁用安全编码;最好的办法是,随着时间的推移,在可能的情况下,将此数据向前迁移到一个允许您在启用安全编码的情况下进行解码的方案。
    • 您可以通过找到一种方法从外部将该类型信息传递给您的类型来做到这一点;一种方法是重用 unarchiver 的 allowedClasses 列表中当前的内容进行解码。然后有人可以请求decodeObject(ofClasses: [&lt;your type&gt;.self, &lt;child object type&gt;.self], forKey: ...),就像他们需要为NSArray 和其他集合一样。如果有人解码您的类型能够指出他们期望的子对象类型,我可以举一个更具说明性的例子。
    猜你喜欢
    • 2015-04-02
    • 1970-01-01
    • 2017-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-25
    相关资源
    最近更新 更多