iOS-Runtime基礎結構

iOSRuntime

Runtime概念:
OC是基於C的,區別於C的一點就是OC屬於動態語言,並且有面向對象的特性。相比於C,函數的調用在編譯的時候會決定調用哪個函數。OC會在編譯和鏈接時做的事情放到了運行時(Runtime)來處理,其調用函數的方法爲msg_send,屬於動態調用,只有在真正運行纔會根據函數名稱找到對應的函數來調用。即使調用未實現的方法在編譯階段也不會報錯(調用階段如果不處理仍會crash),而C語言調用未實現的函數在編譯階段就會報錯。
runtime常用使用場景:
動態添加類的屬性以及方法
方法交換
獲取類的屬性
字典轉模型
等等

數據結構:

//-------- [file:objc-runtime-new.h] --------
struct objc_class : objc_object {
    // Class ISA;
    Class superclass;
    //- 用於快速查找方法執行函數
	//- 增量擴展的哈希表結構
	//- 局部性原理的應用
    cache_t cache;             // formerly cache pointer and vtable
    //存儲類的方法、屬性、遵循的協議等信息的地方
    class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags
    ......
}

在這裏插入圖片描述
對於isa:
指向他的類對象
在這裏插入圖片描述
Root class (class)其實就是 NSObject,NSObject 是沒有超類的,所以 Root class(class)的 superclass 指向 nil。
每個 Class 都有一個 isa 指針指向唯一的 Meta class
Root class(meta)的 superclass 指向 Root class(class),也就是 NSObject,形成一個迴路。
每個 Meta class 的 isa 指針都指向 Root class (meta)。

爲什麼要有元類:
因爲類方法是存儲在元類中的,那麼可不可以把元類幹掉,在類中把實例方法和類方法存在兩個不同的數組中?

答:行是肯定可行的,但是在lookUpImpOrForward執行的時候就得標註上傳入的cls到底是實例對象還是類對象,這也就意味着在查找方法的緩存時同樣也需要判斷cls到底是個啥。

倘若該類存在同名的類方法和實例方法是該調用哪個方法呢?這也就意味着還得給傳入的方法帶上是類方法還是實例方法的標識,SEL並沒有帶上當前方法的類型(實例方法還是類方法),參數又多加一個,而我們現在的objc_msgSend()只接收了(id self, SEL _cmd, …)這三種參數,第一個self就是消息的接收者,第二個就是方法,後續的…就是各式各樣的參數。

通過元類就可以巧妙的解決上述的問題,讓各類各司其職,實例對象就幹存儲屬性值的事,類對象存儲實例方法列表,元類對象存儲類方法列表,完美的符合6大設計原則中的單一職責,而且忽略了對對象類型的判斷和方法類型的判斷可以大大的提升消息發送的效率,並且在不同種類的方法走的都是同一套流程,在之後的維護上也大大節約了成本。
元類的存在巧妙的簡化了實例方法和類方法的調用流程,大大提升了消息發送的效率

對於cache_t:
用散列表來緩存調用過的方法,可以提高訪問方法的速度
增量擴展來提高容量
對於cache_t中的bucket_t:
兩個成員變量key ,IMP

  • key對應selector方法名
  • IMP函數地址

在這裏插入圖片描述
對於class_data_bits_t:
class_rw_t* data() {…}
在這裏插入圖片描述
其中包括一個指向常量的指針 ro,其中存儲了當前類在編譯期就已經確定的屬性、方法以及遵循的協議
const class_ro_t *safe_ro() {…}
在這裏插入圖片描述
Objc 類中的屬性、方法還有遵循的協議等信息都保存在 class_rw_t 中.
類在內存中的位置是編譯期就確定的,類定義的實例方法,會被添加到class_ro_t 的baseMethodList
細看兩個結構體的成員變量會發現很多相同的地方,他們都存放着當前類的屬性、實例變量、方法、協議等等。區別在於:class_ro_t存放的是編譯期間就確定的;而class_rw_t是在runtime時才確定,它會先將class_ro_t的內容拷貝過去,然後再將當前類的分類的這些屬性、方法等拷貝到其中。所以可以說class_rw_t是class_ro_t的超集,當然實際訪問類的方法、屬性等也都是訪問的class_rw_t中的內容。
整體數據結構圖:
在這裏插入圖片描述
Runtime消息機制

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章