是否有可能创建一个最终会返回一个对象的类别(扩展名)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
}
}
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)
| 归档时间: |
|
| 查看次数: |
2423 次 |
| 最近记录: |