【问题标题】:Reference a class name as a variable引用类名作为变量
【发布时间】:2017-05-02 20:14:43
【问题描述】:

我想知道是否有更好的方法来编写这段代码。这是非常多余的,在我这样做之前,我认为应该有一种方法可以使用变量作为类名,但遇到了很多问题并最终以这种方式结束。现在每次看都觉得很烦。我对这个主题进行了相当多的研究,但没有提出任何建议。可能是因为我不确定这样做会被称为什么。

为了论证,假设下面的代码在一个函数中,当一个 SKSpriteNode 被点击时被调用。每个“按钮”都以其将要转换到的场景命名。实际上还有 12 个这样的 case 语句。

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 类的名称都相同。

【问题讨论】:

  • 我投票结束这个问题,因为它属于codereview.stackexchange.com
  • 你不需要像SodHouse(fileNamed:"House")SKScene(fileNamed:"House") 会做你想做的事情,只要你的 sks 文件将自定义类设置为正确的类名
  • @Knight0fDragon 如果你刚才说的没错,那我就可以做我想做的事了。但如果是,那么我在这里这样做的目的是什么?我的印象是必须这样做。
  • 不,这种方式是旧方式(iOS 9 及之前的版本),如果您需要的类有一个独特的特殊功能,那么您只需转换即可。 if let scene = scene as? SodHouse

标签: swift3 sprite-kit


【解决方案1】:

您基本上希望代码看起来像这样(我为您添加了一些守卫):

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

case "newGame":
    //I would avoid using defaults unless you plan on saving when the app exits
    defaults.set(true,forKey: "isFirstRun")
    defaults.set(true,forKey: "isNewGame")

case "IceFishing":
    defaults.set(2, forKey: "currentLocation")

default: break
}

view.presentScene(nextScene!, transition: transition)

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

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

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)

【讨论】:

  • 现在这绝对是有道理的。我只是被告知(或假设)我应该直接引用类名。但我想这样做的目的只是为了当你有一个 SKS 文件和多个可能使用它的类时。但是以我的方式,每个 SKS 文件都有自己的自定义类;这很有意义。灯泡熄灭了!哈哈,谢谢!
  • 1个SKS文件有多个类很傻,有更好的解决方案,比如使用组件
  • 所有这些 UserDefaults 都在游戏会话中使用。我熟悉 UserData 并在其他地方使用它。
  • 您的数字是不变的,但不明白为什么必须将其存储在以后的数据中
  • 所以没有理由再使用OpeningScene(fileNamed:"OpeningScene")?那只是旧语法?我想我只是在为为什么这甚至是一种选择而苦苦挣扎。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-01
  • 2015-08-03
  • 1970-01-01
  • 2011-10-02
  • 2010-09-18
  • 2011-01-06
  • 2016-11-29
相关资源
最近更新 更多