是否可以制作最终会返回投放到instancetype
的对象的类别(扩展名)?我有一个类别来加载SKS文件,但由于此类别适用于SKNode
,因此所有其他子类(如SKScene
或SKEmitterNode
等)也将采用它。
所以我只想避免总是从SKNode
投射到instancetype
。是否可以将返回类型更改为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
}
}
答案 0 :(得分:21)
这可能适合你。我无法测试它,因为我没有多少经验 SpriteKit。但它确实编译并且编译器推断了
的类型let e = SKEmitterNode.unarchiveFromFile("Blah")
是SKEmitterNode。我们的想法是定义一个通用的辅助函数
func unarchiveFromFileHelper<T where T : SKNode>(file: String) -> T
这样
class func unarchiveFromFile(file: String) -> Self {
// define helper function ...
return unarchiveFromFileHelper(file)
}
使用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)
}
}
更新:如果您的目标是iOS 8 / OS X 10.10或更高版本 不再需要自定义的解压缩方法。如中所述 Cannot use unarchiveFromFile to set GameScene in SpriteKit,您可以使用
convenience init?(fileNamed filename: String)
来自SKNode
超类的,例如
if let e = SKEmitterNode(fileNamed: "Blah") {
// ...
}