swift NSSecureCoding如何在子类中覆盖所需的支持SecureCoding

jgwigjjp  于 2023-10-15  发布在  Swift
关注(0)|答案(2)|浏览(141)

我正在尝试使用Swift 5解决iOS项目上的此运行时错误
类必须实现+supportsSecureCoding并返回YES以验证其-initWithCoder的实现:是安全编码兼容的。”UserInfo={NSlogDescription =Class 'Divinstructor.ResultDE'具有支持安全编码的超类,但'Divinstructor.ResultDE'覆盖-initWithCoder:并且不覆盖+supportsSecureCoding。类必须实现+supportsSecureCoding并返回YES以验证其-initWithCoder的实现:是安全编码兼容的。}
然而,我还没有找到一种方法来克服这个错误,因为我试图按照错误指令的结果编译错误,我仍然无法解决
我正在将我的应用程序更新到NSSecureCoding。NSKeyedUnarchiver.unarchiveObject(with:)从iOS 12开始就不推荐使用,必须替换为NSKeyedUnarchiver.unarchivedObject(ofClass:,从:),这实际上是必须从NSCoding转移到NSSecureCoding。
它适用于我修改以符合NSSecureCoding的主类(Result)。其中一个必需的东西是添加符合NSSecureCoding的类

static var supportsSecureCoding: Bool = true

然而,我在运行时面临一个问题(见上文),一个类(ResultDE)是从我的类(Result)继承的。
错误消息说“ResultDE”有一个支持安全编码的超类,但“Divinstructor.ResultDE”覆盖了-initWithCoder:并且不覆盖+supportsSecureCoding。”
然而,我已经尝试了许多选项来覆盖supportsSecureCoding,但没有任何成功。

override public static var supportsSecureCoding: Bool= true

上面明显的一个也会产生编译错误“Cannot override with a stored property 'supportsSecureCoding'”我所有的尝试都导致编译错误。“无法用存储的属性”supportsSecureCoding“重写”
那么,有没有人知道如何在子类中覆盖supportsSecureCoding?
我试图删除man类中supportsSecureCoding的静态(使其不符合协议),但仍然存在“Cannot override with a stored property 'supportsSecureCoding'”编译错误。
下面是重现编译错误短代码

import Foundation

class Result : NSObject, NSSecureCoding {

    static var supportsSecureCoding: Bool = true

    var name: String = "-"

    override init() {
        super.init()
    }

    required init(coder decoder: NSCoder) {
        super.init()
        name = decoder.decodeObject(forKey: "name") as! String
    }
    func encode(with coder: NSCoder) {
        coder.encode(name, forKey: "name")
    }


    class ResultDE: Result {
        override static var supportsSecureCoding: Bool = true

        required init(coder decoder: NSCoder) {
            super.init()
            name = decoder.decodeObject(forKey: "name") as! String
        }
        override func encode(with coder: NSCoder) {
            coder.encode(name, forKey: "name")
        }
    }

}
j7dteeu8

j7dteeu81#

感谢Itai Ferber,这就是做到这一点的方法。

static var supportsSecureCoding: Bool = true

需要更换为

class var supportsSecureCoding: Bool {true}

类可以在子类中重写。
这里的代码示例与修复。

import Foundation

class Result : NSObject, NSSecureCoding {

    public class var supportsSecureCoding: Bool {true}

    var name: String = "-"

    override init() {
        super.init()
    }

    required init(coder decoder: NSCoder) {
        super.init()
        name = decoder.decodeObject(forKey: "name") as! String
    }
    func encode(with coder: NSCoder) {
        coder.encode(name, forKey: "name")
    }


    class ResultDE: Result {
        override public class var supportsSecureCoding: Bool {true} 

        required init(coder decoder: NSCoder) {
            super.init()
            name = decoder.decodeObject(forKey: "name") as! String
        }
        override func encode(with coder: NSCoder) {
            coder.encode(name, forKey: "name")
        }
    }

}
sq1bmfud

sq1bmfud2#

编辑:更新代码以使用Stephane Gasparini supportsSecureCoding

class Result : NSObject, NSSecureCoding {
   class var supportsSecureCoding: Bool { true }

    var name: String = "-"

    override init() {
        super.init()
    }

    required init(coder decoder: NSCoder) {
        super.init()
        name = decoder.decodeObject(forKey: "name") as! String
    }
    func encode(with coder: NSCoder) {
        coder.encode(name, forKey: "name")
    }
}

class ResultDE: Result {
    override class var supportsSecureCoding: Bool { true }

    var title: String = "-"

    override init() {
        super.init()
    }

    required init(coder decoder: NSCoder) {
        super.init(coder: decoder)

        name = decoder.decodeObject(forKey: "title") as! String
    }
    override func encode(with coder: NSCoder) {
        super.encode(with: coder)

        coder.encode(name, forKey: "title")
    }
}

我还添加了这段代码,它会生成一个警告,因为两个类都实现了它。

let r = Result()
    let r1 = ResultDE()

    if let x = r as? NSSecureCoding {
        print("AHA")
    }
    if let x = r1 as? NSSecureCoding {
        print("AHA")
    }

请注意,子类调用super进行编码和解码。
苹果正在做一些非常奇怪的事情,以确保实际的类(而不是子类)返回supportsSecureCoding(恕我直言)。子类和超类具有不同的值有什么意义?如果超类没有提供supportsSecureCoding,那么子类可以提供var。如果超类将其定义为false(为什么要这样做),而子类返回true,OK,这是有意义的。
另一个奇怪的地方是,当我问运行时这两个类是否实现了安全编码时,编译器说true,但运行时失败了。真奇怪

相关问题