3

我在创建使用 NSSecureCoding 及其子类的类时遇到问题。

class ClassA: NSObject, NSSecureCoding {
    public static var supportsSecureCoding: Bool { return true }
}

class ClassB: ClassA {
    public static var supportsSecureCoding: Bool { return true } // "Cannot override static var"
}

我应该这样称呼它,因为 NSObject.h 中的文档说,

此属性必须在所有允许安全编码的类上返回 YES。采用 NSSecureCoding 并覆盖 initWithCoder: 的类的子类也必须覆盖此方法并返回 YES。// 编写解码数据的方法时,应参考安全编码指南。

目标-C:

@property (class, readonly) BOOL supportsSecureCoding;

迅速:

public static var supportsSecureCoding: Bool { get }

我使用的是 Xcode 10.0,在 Swift 4.0 和 Swift 4.2 上都试过了。人们如何解决这个问题?任何帮助表示赞赏。

更新:使用时public class var supportsSecureCoding,它会编译,但在使用 Optimize for Speed 时会在运行时崩溃。

4

4 回答 4

6

似乎 Swift 的当前优化器在其定义与其超类相同时抑制生成覆盖的 getter 方法。多么聪明的优化器!?

这种 hack 会抑制这种过于强烈的优化。

class ClassB: ClassA {

    //...

    static private var secureCoding = true
    override public class var supportsSecureCoding: Bool { return secureCoding }

}

static private let没有相同的效果。因此,当 Swift 优化器更聪明时,上面的代码可能无法正常工作。最好尽快发送错误报告。


似乎 Swift 优化器已经足够聪明,上面的解决方法可能不起作用。(见 Martin R 的评论。)

您可能需要删除private.

class ClassB: ClassA {

    //...

    static var secureCoding = true
    override public class var supportsSecureCoding: Bool { return secureCoding }

}
于 2018-09-30T19:08:31.143 回答
3

static在类声明中是 的别名final class,即不能在子类中覆盖的类型方法。你想要的是一种class 方法

public class var supportsSecureCoding: Bool { return true }

可以在子类中覆盖

override public class var supportsSecureCoding: Bool { return true }
于 2018-09-27T20:24:16.210 回答
0

修复对我有用的

private static var secureCodingWorkaround = true
@objc override public class var supportsSecureCoding: Bool { return secureCodingWorkaround }
于 2018-11-20T09:55:18.357 回答
0

我无法获得上述任何答案。这绝对是苹果方面的一个错误,他们需要解决,因此请确保您将其发送到反馈系统中。我什至没有运气就添加了@objc。

Swift 5.3 编译器现在为未指定安全编码的初始化提供了 NSKeyedArchiver 的弃用消息。但显然该语言不允许在子类中覆盖它。

当我不覆盖变量时,我得到:错误:类“子类”有一个支持安全编码的超类,但“子类”覆盖 -initWithCoder:并且不覆盖 +supportsSecureCoding。该类必须实现 +supportsSecureCoding 并返回 YES 以验证它的 -initWithCoder: 实现是否符合安全编码。(NSInvalidUnarchiveOperationException)

当我覆盖变量时,我得到:“无法覆盖静态变量”

有条件的解决方法:

这种解决方法对我有用,因为我有一个抽象的超类型,因为它永远不会在没有子类型的情况下使用。如果您有类似的设置,这应该适合您:

public class Supertype: NSObject, NSCoding {
     ...

}

亚型:

public class SubType: Supertype, NSSecureCoding {

     public static var supportsSecureCoding = true
     ...
}

这样 var 至少在我使用的所有子类型中。

如果您直接实例化并使用 Supertype,这将不适合您。

于 2021-01-19T00:46:04.813 回答