Cast to typeof(self)

前端 未结 1 627
一个人的身影
一个人的身影 2020-12-31 10:00

Is it possible to make a category (extension) that would eventually return an object casted to instancetype? I have a category to loads SKS files but since this

相关标签:
1条回答
  • 2020-12-31 10:23

    This might work for you. I could not test it because I have not much experience with SpriteKit. But it does compile and the compiler inferred type for

    let e = SKEmitterNode.unarchiveFromFile("Blah")
    

    is SKEmitterNode. The idea is to define a generic helper function

    func unarchiveFromFileHelper<T where T : SKNode>(file: String) -> T 
    

    so that

    class func unarchiveFromFile(file: String) -> Self {
        // define helper function ...
        return unarchiveFromFileHelper(file)
    }
    

    calls the helper function with T == Self.

    extension SKNode {
        class func unarchiveFromFile(file: String) -> Self {
    
            func unarchiveFromFileHelper<T where T : SKNode>(file: String) -> T {
                let path = NSBundle.mainBundle().pathForResource(file, ofType: "sks")
                var sceneData = NSData.dataWithContentsOfFile(path, options: .DataReadingMappedIfSafe, error: nil)
    
                let unarchiver = NSKeyedUnarchiver(forReadingWithData: sceneData)
                unarchiver.setClass(T.classForKeyedUnarchiver(), forClassName: "SKScene")
    
                let scene = unarchiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as T
                unarchiver.finishDecoding()
                return scene
            }
    
            return unarchiveFromFileHelper(file)
        }
    }
    

    Update: If you are targeting iOS 8/OS X 10.10 or later then there is no need for a custom unarchive method anymore. As noted in Cannot use unarchiveFromFile to set GameScene in SpriteKit, you can use

    convenience init?(fileNamed filename: String)
    

    from the SKNode superclass, e.g.

    if let e = SKEmitterNode(fileNamed: "Blah") {
        // ...
    }
    
    0 讨论(0)
提交回复
热议问题