【问题标题】:Is there a way to initialize a class in swift by using a variable which contains the name of the class?有没有办法通过使用包含类名的变量来快速初始化一个类?
【发布时间】:2017-04-11 04:06:27
【问题描述】:

假设我有一个简单的工厂,它返回自定义 ModelObject 类的各种子类,例如:

class func testModelObject(className: String) -> ModelObject
{
   let obj = // instance of the subclass of ModelObject specified by className
   return obj
}

有没有办法做到这一点?当我尝试调用该对象的任何方法时,Swift 会发疯吗?我应该为我的返回类型添加其他内容吗?

【问题讨论】:

  • 为什么要使用字符串而不是ModelObject.Type?
  • 澄清了我的问题。 ModelObject 是一个基类。
  • 我的意思是为什么不使用类似i.stack.imgur.com/yXsS1.png 的东西(抱歉截图,但注释中的内联代码很难看)
  • 我发布的示例过于简单。出于项目特定的原因,我更喜欢使用字符串来定义类型。不过,我移动了一些代码,您指定元类型的想法确实有效。如果无法使用字符串定义元类型,您应该发布您的代码作为答案并解释为什么不能这样做,以便我可以标记解决方案。

标签: swift


【解决方案1】:

为了获得最佳类型安全性,您应该让testModalObject 接受如下元类型:

class ModelObject {
    required init() {}
}

class Subclass: ModelObject {
    required init() { super.init() }
}

func testModalObject(_ type: ModelObject.Type) -> ModelObject {
    return type.init()
}

testModalObject(Subclass.self)

如果你真的需要一个字符串输入,你将需要依赖于 Objective-C 运行时并做一些转换(见how to create instance of a class from a string in swift 3):

@objc
class ModelObject: NSObject {     // <---
    required override init() {}
}

@objc(MOSubclass)    // <-- tell ObjC the name is "MOSubclass" instead of "????.Subclass".
class Subclass: ModelObject {
    required init() { super.init() }
}

func testModalObject(_ typeName: String) -> ModelObject? {
    let cls = NSClassFromString("MO\(typeName)") as? ModelObject.Type
    return cls?.init()
}

testModalObject("Subclass")!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-17
    • 1970-01-01
    • 2010-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多