如何在swift 3中从字符串创建类的实例

Dan*_*ram 27 swift

我尝试使用字符串以多种方式创建类的实例,但没有一个在Swift 3中工作.

下面是我试过的Swift 3之前的解决方案,它们无效

- 使课堂成为一个客观的课程

@objc(customClass)
class customClass {
    ...
}

//Error here: cannot convert value of type 'AnyClass?' to expected argument type 'customClass'
let c: customClass = NSClassFromString("customClass")
Run Code Online (Sandbox Code Playgroud)

- 使用NSString值指定类(使用和不使用@objc属性)

@objc(customClass)
class customClass {
    ...
}

//Error here: cannot convert value of type 'String' to expected argument type 'AnyClass' (aka 'AnyObject.Type')
var className = NSStringFromClass("customClass")

let c: customClass = NSClassFromString(className)
Run Code Online (Sandbox Code Playgroud)

我做的不对,但没有在网上找到任何解决方案.

如何在Swift 3中使用字符串创建类的实例?

Nic*_* xu 29

你可以试试这个:

func stringClassFromString(_ className: String) -> AnyClass! {

    /// get namespace
    let namespace = Bundle.main.infoDictionary!["CFBundleExecutable"] as! String;

    /// get 'anyClass' with classname and namespace 
    let cls: AnyClass = NSClassFromString("\(namespace).\(className)")!;

    // return AnyClass!
    return cls;
}
Run Code Online (Sandbox Code Playgroud)

像这样使用func:

class customClass: UITableView {

    }   
let myclass = stringClassFromString("customClass") as! UITableView.Type
let instance = myclass.init()
Run Code Online (Sandbox Code Playgroud)

  • 注意:如果您的可执行文件名称中有空格,我认为这不起作用。我们不是使用CFBundleExecutable,而是使用CFBundleName,除非我们用下划线替换了空格,否则它不起作用。在这个(有些令人困惑的)博客文章中提出了建议:https://medium.com/@maximbilan/ios-objective-c-project-nsclassfromstring-method-for-swift-classes-dbadb721723。帖子中的代码有效,但是实际的帖子中谈到了使用appname和目标名称,这与他们的代码不同。 (2认同)

小智 6

如果您的项目包含空格,则应将空格替换为“_”

像这样的东西

let namespace = (Bundle.main.infoDictionary!["CFBundleExecutable"] as! String).replacingOccurrences(of: " ", with: "_")
let cls = NSClassFromString("\(namespace).\(className)")! as! AnyClass
Run Code Online (Sandbox Code Playgroud)


Dan*_*orm 5

苹果提供了一种无需使用即可实现此目的的方法NSClassFromString

Bundle.main.classNamed("MyClassName")

https://developer.apple.com/documentation/foundation/bundle/1407299-classnamed

  • 不要忘记添加“MyApp”。作为“MyClassName”的前缀,其中 MyApp 是您的包名称。否则你可能会得到一个零值。 (3认同)