NSClassFromString類似反射,也就是通過字符串獲取到類。
對于系統(tǒng)類而言,直接使用名稱就可以獲取到對應(yīng)的類,如NSClassFromString("UIViewController")可以獲取到UIViewController.Type,這樣的話,就可以通過獲取到的AnyClass對象,進行類型強轉(zhuǎn)之后,調(diào)用對應(yīng)的init方法,生成相應(yīng)對象。
1、在Swift中,對于我們的自定義類而言,需要多一步操作。因為直接把類名作為參數(shù)調(diào)用NSClassFromString,會發(fā)現(xiàn)返回值為nil,這是因為自定義的類實際上還存在一個module名字,也就是類定義在內(nèi)存中的名稱是{moduleName}.{className},所以在調(diào)用之前需要進行一下處理。如下面的代碼,就是進行了相應(yīng)的處理
//MARK:--初始化對象--Swift
extension SwiftMediator {
/// 反射VC初始化并且賦值
/// - Parameters:
/// - moduleName: 組件boundle名稱,不傳則為默認命名空間
/// - vcName: VC名稱
/// - dic: 參數(shù)字典//由于是KVC賦值,必須要在參數(shù)上標記@objc
@discardableResult
public func initVC(_ vcName: String,
moduleName: String? = nil,
dic: [String : Any]? = nil) -> UIViewController?{
var namespace = Bundle.main.infoDictionary!["CFBundleExecutable"] as! String
if let name = moduleName {
namespace = name
}
let className = "\(namespace).\(vcName)"
guard let cls = NSClassFromString(className) as? UIViewController.Type else { return nil }
let controller = cls.init()
setObjectParams(obj: controller, paramsDic: dic)
return controller
}
(lldb) po namespace
"ZYHome"
(lldb) po vcName
"CarHomeViewController"
(lldb) po className
"ZYHome.CarHomeViewController"
(lldb) po cls
ZYHome.CarHomeViewController
之所以會寫namespace,是因為在iOS中moduleName就是應(yīng)用的名稱。這個樣子就可以真正的獲取到對應(yīng)的Class了。
2、在OC中,不需要在{className}之前添加{moduleName},使用{className}就可以直接獲取對應(yīng)的類。