我在创建使用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。 //编写用于解码数据的方法时,应查阅《安全编码指南》。
Objective-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
时,它可以编译,但是使用“优化速度”时,它将在运行时崩溃。
答案 0 :(得分:4)
当它的定义与其父类相同时,Swift的当前优化器似乎会抑制生成重写的getter方法。多么聪明的优化器!?
这种黑客行为会抑制这种过强的优化。
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 }
}
答案 1 :(得分:1)
static
是final class
的别名,即类型方法
不能在子类中覆盖。您想要的是一种class
方法
public class var supportsSecureCoding: Bool { return true }
可以在子类中用
覆盖override public class var supportsSecureCoding: Bool { return true }
答案 2 :(得分:0)
修复了我的问题
private static var secureCodingWorkaround = true
@objc override public class var supportsSecureCoding: Bool { return secureCodingWorkaround }
答案 3 :(得分:0)
我无法获得上述任何答案。这绝对是 Apple 方面的一个错误,他们需要解决,因此请确保将其发送到反馈系统中。我什至没有运气就添加了@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,这对您不起作用。