`Self` cast fails only when optimised?

I found an unexpected cast failure involving a use of Self when the code was optimised, but not in debug:

extension SKNode {

     // Creates an SKNode from the given bundle.
    static func decode(fileNamed name: String, in bundle: Bundle) -> Self? {

        guard let url = bundle.url(forResource: name, withExtension: "sks"),
            let data = try? Data(contentsOf: url),
            let node = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) else {
            return nil
        }

        return node as? Self
    }
}

At a later location I ask to decode an SKEmitterNode:

let myNode = SKEmitterNode.decode(fileNamed: "myFile", in: .myFrameworkBundle)!

When this is in debug, the cast to SKEmitterNode happens correctly. When optimised (with or without WMO) the cast fails. Is this a supported configuration, known bug etc?

Thanks.

Not sure if this supposed to work at all because SKEmitterNode is not a final class. Self was always a tricky fella, especially on classes as this functionality got added not that long ago.

Can you try moving that code into a protocol extension and conform the class.

protocol _SKNodeExtension: SKNode {}
extension _SKNodeExtension {
  // Creates an SKNode from the given bundle.
  static func decode(fileNamed name: String, in bundle: Bundle) -> Self? {
    guard
      let url = bundle.url(forResource: name, withExtension: "sks"),
      let data = try? Data(contentsOf: url),
      let node = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data)
    else {
      return nil
    }
    return node as? Self
  }
}

extension SKNode: _SKNodeExtension {}
Terms of Service

Privacy Policy

Cookie Policy