`supportsSecureCoding` 在使用 Optimize for Speed 选项时崩溃
`supportsSecureCoding` crashes when using Optimize for Speed option
我在创建使用 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 中的文档说,
This property must return YES on all classes that allow secure coding. Subclasses of classes that adopt NSSecureCoding and override initWithCoder: must also override this method and return YES.
// The Secure Coding Guide should be consulted when writing methods that decode data.
Objective-C:
@property (class, readonly) BOOL supportsSecureCoding;
Swift:
public static var supportsSecureCoding: Bool { get }
我正在使用 Xcode 10.0,在 Swift 4.0 和 Swift 4.2 上都试过了。
人们如何解决这个问题?感谢任何帮助。
更新:
使用 public class var supportsSecureCoding
时,它可以编译,但在使用“优化速度”时会在运行时崩溃。
static
在 class 声明中是 final class
的别名,即类型方法
不能在 subclass 中覆盖。你想要的是class
方法
public class var supportsSecureCoding: Bool { return true }
可以在子class中用
覆盖
override public class var supportsSecureCoding: Bool { return true }
当 Swift 的定义与其超类相同时,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 }
}
对我有用的修复
private static var secureCodingWorkaround = true
@objc override public class var supportsSecureCoding: Bool { return secureCodingWorkaround }
我无法得到上述任何答案。这绝对是 Apple 方面的一个错误,他们需要解决,因此请确保您将其发送到反馈系统中。我什至没有运气就添加了@objc。
Swift 5.3 编译器现在为未指定安全编码的初始化给出了 NSKeyedArchiver 的弃用消息。但显然该语言不允许在 subclasses 中覆盖它.
当我不覆盖变量时,我得到:
错误:Class 'Subclass' 有一个支持安全编码的 superclass,但是 'Subclass' 覆盖了 -initWithCoder: 而没有覆盖 +supportsSecureCoding。 class 必须实现 +supportsSecureCoding 和 return YES 以验证它的 -initWithCoder: 实现是否符合安全编码。 (NSInvalidUnarchiveOperationException)
当我覆盖变量时,我得到:“无法覆盖静态变量”
有条件的解决方法:
这个解决方法对我有用,因为我有一个超级类型,它有点抽象,因为它永远不会在没有子类型的情况下使用。如果您有类似的设置,这应该适合您:
public class Supertype: NSObject, NSCoding {
...
}
子类型:
public class SubType: Supertype, NSSecureCoding {
public static var supportsSecureCoding = true
...
}
这样 var 至少在我使用的所有子类型中都是。
如果您直接实例化并使用 Supertype,这对您不起作用。
我在创建使用 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 中的文档说,
This property must return YES on all classes that allow secure coding. Subclasses of classes that adopt NSSecureCoding and override initWithCoder: must also override this method and return YES. // The Secure Coding Guide should be consulted when writing methods that decode data.
Objective-C:
@property (class, readonly) BOOL supportsSecureCoding;
Swift:
public static var supportsSecureCoding: Bool { get }
我正在使用 Xcode 10.0,在 Swift 4.0 和 Swift 4.2 上都试过了。 人们如何解决这个问题?感谢任何帮助。
更新:
使用 public class var supportsSecureCoding
时,它可以编译,但在使用“优化速度”时会在运行时崩溃。
static
在 class 声明中是 final class
的别名,即类型方法
不能在 subclass 中覆盖。你想要的是class
方法
public class var supportsSecureCoding: Bool { return true }
可以在子class中用
覆盖override public class var supportsSecureCoding: Bool { return true }
当 Swift 的定义与其超类相同时,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 }
}
对我有用的修复
private static var secureCodingWorkaround = true
@objc override public class var supportsSecureCoding: Bool { return secureCodingWorkaround }
我无法得到上述任何答案。这绝对是 Apple 方面的一个错误,他们需要解决,因此请确保您将其发送到反馈系统中。我什至没有运气就添加了@objc。
Swift 5.3 编译器现在为未指定安全编码的初始化给出了 NSKeyedArchiver 的弃用消息。但显然该语言不允许在 subclasses 中覆盖它.
当我不覆盖变量时,我得到: 错误:Class 'Subclass' 有一个支持安全编码的 superclass,但是 'Subclass' 覆盖了 -initWithCoder: 而没有覆盖 +supportsSecureCoding。 class 必须实现 +supportsSecureCoding 和 return YES 以验证它的 -initWithCoder: 实现是否符合安全编码。 (NSInvalidUnarchiveOperationException)
当我覆盖变量时,我得到:“无法覆盖静态变量”
有条件的解决方法:
这个解决方法对我有用,因为我有一个超级类型,它有点抽象,因为它永远不会在没有子类型的情况下使用。如果您有类似的设置,这应该适合您:
public class Supertype: NSObject, NSCoding {
...
}
子类型:
public class SubType: Supertype, NSSecureCoding {
public static var supportsSecureCoding = true
...
}
这样 var 至少在我使用的所有子类型中都是。
如果您直接实例化并使用 Supertype,这对您不起作用。