反射機制:
對于任意一個類,都能夠知道這個類的屬性和方法;對于任意一個對象,都能夠調用它的任意一本方法和屬性。這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。
在OC中的反射機制:
NSClassFromString
isKindOfClass
isMemberOfClass
responsesToSelector
performSelector或objc_msgSend間接調用方法
反射機制的利用:
團隊開發中,A開發一個類,B開發一個類,但是A想使用B的東西,但是B還沒寫好,這時A就可以通過使用NSClassFromString,減少對B開發代碼的依賴性
反射機制的實際應用:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
/*
代碼中的?都是可選解包,發送消息,不參與計算
所有的?都是Xcode自動生成的
*/
window = UIWindow()
window?.backgroundColor = UIColor.white
//設置跟控制器要添加命名空間(默認是項目名稱,最好不要有特殊符號)
// let vc = ViewController()
let clsName = "反射機制.ViewController"
let cls = NSClassFromString(clsName) as? UIViewController.Type
//使用類來創建視圖控制器
let vc = cls?.init()
window?.rootViewController = vc
window?.makeKeyAndVisible()
return true
}
從info.plist中抽取命名空間
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
window = UIWindow()
window?.backgroundColor = UIColor.white
//因為字典是可選的,因此需要解包再取值,如果字典為nil就不取值
//通過key從子點中取值,如果key錯了,就沒有值了
let ns = Bundle.main.infoDictionary?["CFBundleName"] as? String ?? ""
let clsName = ns+"."+"ViewController"
let cls = NSClassFromString(clsName) as? UIViewController.Type
//使用類來創建視圖控制器
let vc = cls?.init()
window?.rootViewController = vc
window?.makeKeyAndVisible()
return true
}
抽取nameSpace的計算型屬性
extension Bundle{
//返回命名空間字符串
// func nameSpace() -> String {
// return Bundle.main.infoDictionary?["CFBundleName"] as? String ?? ""
// }
//計算型屬性
var nameSpace: String{
return Bundle.main.infoDictionary?["CFBundleName"] as? String ?? ""
}
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
window = UIWindow()
window?.backgroundColor = UIColor.white
//利用方法
//let ns = Bundle.main.nameSpace()
//利用計算型屬性
let ns = Bundle.main.nameSpace
let clsName = ns+"."+"ViewController"
let cls = NSClassFromString(clsName) as? UIViewController.Type
//使用類來創建視圖控制器
let vc = cls?.init()
window?.rootViewController = vc
window?.makeKeyAndVisible()
return true
}
總結:
1、知道Swift中有命名空間
-在同一個命名空間下,全局共享
-第三方框架使用Swift,如果直接拖拽到項目中,就從屬于同一個命名空間,很可能會沖突
-以后要盡量使用Cocoapod
2、重點要知道Swift中NSClassFromString(反射機制)的寫法
- 反射機制的最重要目的是為了解耦
- 提示:反射機制和工廠方法,第一印象會發現一個簡單的功能,寫的會很復雜。但是封裝的很好,而且彈性很大。