let ocCls: AnyClass? =NSClassFromString("XQMessageTableViewCell") let ocConcreteCls: XQMessageTableViewCell.Type= ocCls as!XQMessageTableViewCell.Type let aocObj = ocConcreteCls.init(style: .default, reuseIdentifier: "reuseIdentifier") print(aocObj)
已知一个Swift类名,通过该类名字符串来创建一个实例:
1 2 3 4
let namespace =Bundle.main.infoDictionary!["CFBundleExecutable"] as!String let s2: People.Type=NSClassFromString(namespace +"."+"People") as!People.Type let s2obj = s2.init() print(s2obj)
对于Swift的类,如果需要通过该类名字符串来创建一个实例,则必须指定命名空间.
错误写法:没有拼接命名空间.
1 2 3 4
let swiftCls: AnyClass? =NSClassFromString("People") //这里其实是nil. let swiftConcreteCls: People.Type= swiftCls as!People.Type let swiftobj = swiftConcreteCls.init() print(swiftobj)
封装
对于混编工程,为了使用方便,可以使用下面的封装方法.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classZAEClassUtil: NSObject { @objcstaticfuncgetClassType(namespace: String?, className: String) -> AnyClass? { var rs: AnyClass? =NSClassFromString(className) if rs ==nil { let ns = namespace ??Bundle.main.infoDictionary!["CFBundleExecutable"] as!String rs =NSClassFromString(ns +"."+ className) //如果类名对应的是Swift类则必须要拼接命名空间,如果是OC的则不需要. } return rs } @objcstaticfuncgetClassString(cls: AnyClass) -> String { let name =NSStringFromClass(cls) if (name.contains(".")) { return name.components(separatedBy: ".")[1]; } else { return name; } } }
使用如下:
1 2 3 4 5 6 7
let s3: XQRedView.Type=ZAEClassUtil.getClassType(namespace: nil, className: "XQRedView") as!XQRedView.Type let s3obj = s3.init(frame: .zero) print(s3obj) let s4: XQMessageTableViewCell.Type=ZAEClassUtil.getClassType(namespace: nil, className: "XQMessageTableViewCell") as!XQMessageTableViewCell.Type let s4obj = s4.init(style: .default, reuseIdentifier: "reuseIdentifier") print(s4obj, ZAEClassUtil.getClassString(cls: s4))