Swift3 将类名作为变量引用

Swift3 将类名作为变量引用,swift3,sprite-kit,Swift3,Sprite Kit,我想知道是否有更好的方法来编写这段代码。这是非常冗余的,在我这样做之前,我认为应该有一种方法可以使用变量作为类名,但是遇到了很多问题,最终以这种方式结束。现在每次我看着它,它都会让我烦恼。我在这个问题上做了很多研究,但没有得出任何结论。可能是因为我不确定这样做叫什么 为了便于讨论,假设以下代码位于一个函数中,该函数在点击SKSpriteNode时被调用。每个“按钮”都是根据要转换到的场景命名的。实际上,这些case语句还有12条 let name = sender.name switch(nam

我想知道是否有更好的方法来编写这段代码。这是非常冗余的,在我这样做之前,我认为应该有一种方法可以使用变量作为类名,但是遇到了很多问题,最终以这种方式结束。现在每次我看着它,它都会让我烦恼。我在这个问题上做了很多研究,但没有得出任何结论。可能是因为我不确定这样做叫什么

为了便于讨论,假设以下代码位于一个函数中,该函数在点击SKSpriteNode时被调用。每个“按钮”都是根据要转换到的场景命名的。实际上,这些
case
语句还有12条

let name = sender.name
switch(name){
    case "newGame":
        defaults.set(true,forKey: "isFirstRun")
        defaults.set(true,forKey: "isNewGame")
        let transition = SKTransition.crossFade(withDuration: 1.0)
        let nextScene = Setup(fileNamed:"Setup")
        nextScene?.scaleMode = .aspectFill
        scene?.view?.presentScene(nextScene!, transition: transition)
        break
    case "IceFishing":
        defaults.set(2, forKey: "currentLocation")
        let transition = SKTransition.crossFade(withDuration: 1.0)
        let nextScene = IceFishing(fileNamed:"IceFishing")
        nextScene?.scaleMode = .aspectFill
        scene?.view?.presentScene(nextScene!, transition: transition)
        break
    case "OpeningScene":
        let transition = SKTransition.crossFade(withDuration: 1.0)
        let nextScene = OpeningScene(fileNamed:"OpeningScene")
        nextScene?.scaleMode = .aspectFill
        scene?.view?.presentScene(nextScene!, transition: transition)
        break
    case "House":
        let transition = SKTransition.crossFade(withDuration: 1.0)
        let nextScene = SodHouse(fileNamed:"House")
        nextScene?.scaleMode = .aspectFill
        scene?.view?.presentScene(nextScene!, transition: transition)
        break
    default:
        break
}
我认为(或希望)有一种方法可以做到像

let name = sender.name
let _Class = name as! SKScene //Not right, but i was guessing

let transition = SKTransition.crossFade(withDuration: 1.0)
let nextScene = _Class(fileNamed:name)
nextScene?.scaleMode = .aspectFill
scene?.view?.presentScene(nextScene!, transition: transition)

所有sks文件和Swift类的名称都相同。

您基本上希望代码如下所示(我为您添加了一些防护措施):

基本上,我们所做的是依靠sks文件中的custom class字段为我们加载自定义类

编辑:现在为了进一步清理代码,我将放弃使用默认值。您应该只在希望跨游戏会话而不是跨游戏保存数据时才使用此选项

let name = sender.name
let transition = SKTransition.crossFade(withDuration: 1.0)
guard let nextScene = SKScene(fileNamed:sender.name) else {fatalError("unable to find next scene")}
guard let scene = scene else {fatalError("unable to find scene")}
guard let view = scene.view else {fatalError("unable to find view")}

nextScene.scaleMode = .aspectFill

nextScene.userData += scene.userData
//Move these to the SKS file under UserData section, then you can pull it using scene.userData?
//    defaults.set(2, forKey: "currentLocation")    
//    defaults.set(true,forKey: "isFirstRun") 
//    defaults.set(true,forKey: "isNewGame")

view.presentScene(nextScene!, transition: transition)

我投票将这个问题作为离题题来结束,因为它属于你,你不需要做类似于
SodHouse(filename:“House”)
SKScene(filename:“House”)
的事情,只要你的sks文件将自定义类设置为正确的类,它就会做你想做的事情name@Knight0fDragon如果你刚才说的是正确的,那我就可以做我想做的事了。但如果是的话,那么我这样做的目的是什么?我的印象是必须这样做。不,这种方式是旧的方式(iOS 9和之前的版本),如果你需要一个特殊的类函数,那么你只需要强制转换<代码>如果让场景=场景为?索德豪斯现在这绝对是有道理的。我只是被告知(或假设)我应该直接引用类名。但我认为这样做的目的只是为了当您有一个SKS文件和多个可能使用它的类时。但以我的方式,每个SKS文件都有自己的自定义类;这很有道理。灯泡灭了!哈哈,谢谢!有一个包含多个类的SKS文件是愚蠢的,有更好的解决方案,比如使用组件。所有这些用户默认值都在游戏会话中使用。我熟悉用户数据,并在其他地方使用它。不过,您的数字是恒定的,不明白为什么必须将其存储在以后的数据中,所以没有理由再使用
OpeningScene(文件名为:“OpeningScene”)
?那只是旧语法?我想我只是在挣扎为什么这是一个选择。
let name = sender.name
let transition = SKTransition.crossFade(withDuration: 1.0)
guard let nextScene = SKScene(fileNamed:sender.name) else {fatalError("unable to find next scene")}
guard let scene = scene else {fatalError("unable to find scene")}
guard let view = scene.view else {fatalError("unable to find view")}

nextScene.scaleMode = .aspectFill

nextScene.userData += scene.userData
//Move these to the SKS file under UserData section, then you can pull it using scene.userData?
//    defaults.set(2, forKey: "currentLocation")    
//    defaults.set(true,forKey: "isFirstRun") 
//    defaults.set(true,forKey: "isNewGame")

view.presentScene(nextScene!, transition: transition)