Ios Swift:按整数加载级别类

Ios Swift:按整数加载级别类,ios,swift,class,Ios,Swift,Class,我正在做一个有很多关卡的快速游戏。每个级别都位于一个具有连续名称的文件中: Level1.swift Level2.swift Level3.swift ... 每个文件中都有一个类,类名与文件名相同 一切都是一个类的原因是因为所有的类都共享一个基类的类似函数,也因为有很多共享变量 问题是,我不知道如何只使用整数加载级别,而不执行此类灾难: switch Int(level)! { case 1: newScene = Level1(size: frame.size) case

我正在做一个有很多关卡的快速游戏。每个级别都位于一个具有连续名称的文件中:

Level1.swift
Level2.swift
Level3.swift
...
每个文件中都有一个类,类名与文件名相同

一切都是一个类的原因是因为所有的类都共享一个基类的类似函数,也因为有很多共享变量

问题是,我不知道如何只使用整数加载级别,而不执行此类灾难:

switch Int(level)! {
  case 1:
    newScene = Level1(size: frame.size)
  case 2:
    newScene = Level2(size: frame.size)
  case 3:
    newScene = Level3(size: frame.size)
  ...
我不能使用
SKScene(filename:)
,因为我没有任何.sks文件,只有实际的类。如果我可以简单地使用Bundle.main.url加载一个带有音频文件的场景,那就太好了,但这是不可能的。我尝试使用一个带有默认行为扩展的协议,但我仍然想不出一种方法来很好地加载它。任何帮助都将不胜感激。

我认为您的“灾难性”解决方案确实提供了Swift中最干净、经过类型检查的解决方案。如果您想基于仅在运行时已知的名称初始化类,则必须进入ObjC领域:

首先,使基类继承自
NSObject
(如果尚未继承):

以下是如何使用它:

let levelId = 2

// Module Name = Product Name from your Build Settings, unless you put
// the Level classes into sub-namespace
let className = "ModuleName.Level\(levelId)"    

let LevelClass = NSClassFromString(className) as! Level.Type

// At build time, the compiler sees this as an object of type Level,
// but it's actually a Level2 object. You can cast it to Level2 if
// you need to do something specific to that level.
let level = LevelClass.init(size: frame.size)       

您需要为您的类获取classString,幸运的是,您的类提供了一个公共模式,因此这对您来说很容易

在我的例子中,这个的输出是:

这个字符串就是我们需要的:TempCode.Level

我要加载的级别为2级

我的类的真实名称是:TempCode.Level2

创建级别2

创建了一个类型为Level2的类

let levelId = 2

// Module Name = Product Name from your Build Settings, unless you put
// the Level classes into sub-namespace
let className = "ModuleName.Level\(levelId)"    

let LevelClass = NSClassFromString(className) as! Level.Type

// At build time, the compiler sees this as an object of type Level,
// but it's actually a Level2 object. You can cast it to Level2 if
// you need to do something specific to that level.
let level = LevelClass.init(size: frame.size)       
import Foundation

class Level  {
    required init() {}
}

class Level1 : Level {
     required init() {
        print("Created Level 1")
    }
}
class Level2 : Level {
    required  init() {
        print("Created Level 2")
    }
}

var myLevelClassRealName = NSStringFromClass(Level.self)
print("This String is what we need : \(myLevelClassRealName)")

var level = 2
print("The Level I want to load is Level # \(level)")
myLevelClassRealName = myLevelClassRealName + "\(level)"
print("Real name for my class is   : " + myLevelClassRealName)

let myLookupClass = NSClassFromString(myLevelClassRealName) as! Level.Type
let currentLevel = myLookupClass.init()

print("Created a class of type     : \(type(of: currentLevel))")