转换为typeof(self)

Ben*_*air 11 swift

是否有可能创建一个最终会返回一个对象的类别(扩展名)instancetype?我有一个类别来加载SKS文件,但由于这个类别适用于SKNode所有其他子类,如SKSceneSKEmitterNode等...也将采用它.

所以,我只是想避免总是从铸造SKNodeinstancetype.是否可以将返回类型更改为instancetype并确保编译器对返回值感到满意?

我想我可以使用-> Self返回类型,但后来我不知道如何转换scene为instancetype所以这个东西会编译..

例如:

SKEmitterNode.unarchiveFromFile("Blah") 会返回一个实例 SKEmitterNode

extension SKNode {
    class func unarchiveFromFile(file: String) -> SKNode {
        let path = NSBundle.mainBundle().pathForResource(file, ofType: "sks")
        var sceneData = NSData.dataWithContentsOfFile(path, options: .DataReadingMappedIfSafe, error: nil)

        let unarchiver = NSKeyedUnarchiver(forReadingWithData: sceneData)
        unarchiver.setClass(self.classForKeyedUnarchiver(), forClassName: "SKScene")

        let scene = unarchiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as SKNode
        unarchiver.finishDecoding()

        return scene
    }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*n R 22

这可能对你有用.我无法测试它因为我对SpriteKit没有多少经验.但它确实编译和编译推断类型

let e = SKEmitterNode.unarchiveFromFile("Blah")
Run Code Online (Sandbox Code Playgroud)

是SKEmitterNode.我们的想法是定义一个通用的辅助函数

func unarchiveFromFileHelper<T where T : SKNode>(file: String) -> T 
Run Code Online (Sandbox Code Playgroud)

以便

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

调用辅助函数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)
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:如果您的目标是iOS 8/OS X 10.10或更高版本,则不再需要自定义的归档方法.如 无法使用unarchiveFromFile在SpriteKit中设置GameScene,您可以使用

convenience init?(fileNamed filename: String)
Run Code Online (Sandbox Code Playgroud)

来自SKNode超类,例如

if let e = SKEmitterNode(fileNamed: "Blah") {
    // ...
}
Run Code Online (Sandbox Code Playgroud)