swiftnssecurecoding

`supportsSecureCoding` crashes when using Optimize for Speed option


I'm having trouble creating classes that uses NSSecureCoding and its subclasses.

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"
}

I'm supposed to call this since the documentation in NSObject.h says,

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 }

I am using Xcode 10.0, tried on both Swift 4.0 and Swift 4.2. How are people getting around this? Any help is appreciated.

UPDATE: When using public class var supportsSecureCoding, it compiles but it crashes at runtime when Optimize for Speed is used.


Solution

  • Seems the current optimizer of Swift suppresses to generate the overridden getter method when its definition is the same as its superclass. What a clever optimizer!?

    This sort of hack would suppress such too strong optimization.

    class ClassB: ClassA {
    
        //...
    
        static private var secureCoding = true
        override public class var supportsSecureCoding: Bool { return secureCoding }
    
    }
    

    static private let does not have the same effect. So, when the Swift optimizer being more clever, the code above may not work. Better send a bug report soon.


    Seems the Swift optimizer is already clever enough and the workaround above may not work. (See Martin R's comment.)

    You may need to remove private.

    class ClassB: ClassA {
    
        //...
    
        static var secureCoding = true
        override public class var supportsSecureCoding: Bool { return secureCoding }
    
    }