RunTime簡稱運行時。OC就是運行時機制,其中最主要的是消息機制。OC的函數,屬於動態調用過程,在編譯的時候並不能決定真正調用哪個函數,只有在真正運行的時候才會根據函數的名稱找到對應的函數來調用.
objc_msgSend,只有對象才能發送消息,因此以objc開頭.
對象根據方法編號SEL去映射表查找對應的方法實現
1,交換方法
2,動態添加方法(感覺沒啥用,還不如直接分類)
3,給分類添加屬性
4,字典轉模型
5,快速歸檔解檔
6,獲取類的所有的屬性和方法
當系統提供的控件不能滿足我們的需求的時候,我們可以
1:通過繼承系統控件,重寫系統的方法,來擴充子類的行為。
2:當需要為系統類擴充別的屬性或是方法的時候,與哪個類有關系,就為哪個類創建分類(不能在分類中重寫系統方法,因為會把系統的功能給覆蓋掉,而且分類中不能調用super)。
3:利用runtime修改系統的類,交換方法(對象 發送消息 調用的方法被交換了,聲明不會交換,所以會寫成聲明和調用是壹個方法,實際交換方法後,對象調用的是交換後的方法)
交換的實際上是交換的方法列表和IMP(方法實現的對應關系)原理圖如下
交換前:
交換後:
通過為要修改的類添加壹個分類來實現。例如交換系統的imageNamed方法。
1,添加分類(UIImage的分類Image)
1.1定義壹個方法調用交換後的系統方法
1.2,在+ (void)load中交換方法(// 把類加載進內存的時候調用,只會調用壹次)
開發使用場景:如果壹個類方法非常多,加載類到內存的時候也比較耗費資源,需要給每個方法生成映射表,可以使用動態給某個類添加方法解決(通過performSelector調用,class_addMethod實現)。
經典面試題:有沒有使用performSelector,其實主要想問妳有沒有動態添加過方法。
簡單使用
分類不能直接添加屬性的原因:
在分類裏使用@property聲明屬性,只是將該屬性添加到該類的屬性列表,並聲明了setter和getter方法,但是沒有生成相應的成員變量,也沒有實現setter和getter方法。所以說分類不能添加屬性。使用@property的時候,系統會自動生成帶“_”的成員變量和該變量的setter和getter方法。也就是說,屬性相當於壹個成員變量加getter和setter方法。
解決辦法:在分類裏使用@property聲明屬性後,即使實現了setter和getter方法,也仍然沒有添加帶“_”的成員變量,也就是說,在setter和getter方法裏仍然不能直接訪問以下劃線開頭的成員變量,因為在分類裏用@property聲明屬性時系統並沒有添加以“”開頭的成員變量。此時要達到添加的目的可以 使用運行時的關聯對象 。
原理:給壹個類聲明屬性,其實本質就是給這個類添加關聯
簡單示例
思路:利用運行時,遍歷模型中所有屬性,根據模型的屬性名,去字典中查找key,取出對應的值,給模型的屬性賦值。
在Controller中實現具體的存取操作
KVO和KVC可以利用這個。