Runtime 基礎知識
- 數據結構
- 類對象與元類對象
- 消息傳遞機制
- 方法緩存
- 消息轉發
- Method-Swizzling
- 動態添加方法
- 動態方法解析
基礎數據結構
- objc_object
- objc_class
- isa指針
- method_t
objc_object
- 我們在OC中使用的所有的對象都是id類型的。id類型的對象對應到runtime當中就是 id == objc_object,就是objc_object 這樣的一個結構體
- objc_object 數據結構
- isa_t 共用體 。
- 關於isa操作相關的方法 例如:通過objc_object這個結構來獲取isa所指向的類對象。 類對象通過isa指針指向它的元類對象
- 弱引用相關的方法 這個結構是否曾經有過弱引用指針
- 關聯對象相關方法 給這個對象設置類一些關聯屬性等,關聯屬性的相關方法也體現在objc_object這個結構體當中。
- 內存管理相關的一些方法實現 包括 retain、release、mrc、arc等這些方法實現都是封裝在objc_object這個結構體當中。
objc_class
- Class == objc_class
- Class 代表的是一個類,對應的就是objc_class , class 就是一個對象,因爲objc_class 繼承字objc_class
- objc_class Class superClass Class類型的superClass 就是類對象的父類 ,通過superClass這個成員變量來實現的
- cache_t cache 緩存 成員變量
- class_data_bits bits 數據結構 , 在類中定義的變量、屬性、方法都是存儲在bits 這個成員結構中
isa指針
- 共用體 isa_t 是C/C++中的共用體 在OC中定義了 isa_t 這樣的一個名稱
如果是64位機器就是64個0. - 指針型isa -> isa的值代表Class的地址 比如我們使用objc_object這個對象的時候,可以通過isa的內容,來獲取它類對象的地址
- 非指針型的isa -> isa的值的部分代表Class的地址 比如64位架構 可能有32位或者40位用來存放Class的地址,因爲在尋址的過程中就能夠找到Class的地址,多出來的這些位數可以用來存儲其他的相關內容來達到節省內存的目的
- 這也就是產生兩種類型的isa的原因
isa指針是什麼含義
- 指針型isa
- 非指針型的isa
isa的指向
- 對象 -> 類對象
- 比如一個實例 在runtime中就是objc_object 中有 isa指針 -> Class
- 類對象 指向 元類對象
- Class 代表着 objc_class 繼承自 objc_object所以Class也是一種對象,它的isa指向Metaclass元類對象
- 當我們調用一個isa指針的實例方法, 實際上是通過isa指針去它的類對象當中去查找
- 調用類對象的類方法實際是 通過類對象的isa指針去它的元類對象中去查找
cache_t
- 用於快速查找方法執行函數 比如在調用一個方法的時候如果有一個緩存就不用每次都到方法列表中逐一遍歷去查找了。可以提高方法調用的速度或者是消息傳遞的速度
- 可增量擴展的哈希表結構 增量擴展: 當儲存的量增大的時候會擴大其內存空間來支持更多的緩存 用哈希表來實現這個結構主要是爲了提高查找效率
- 是局部性原理的最佳應用 通常調用的方法通常就那麼幾個,會把調用頻率最高的方法緩存起來,下次命中率就會更高
bucket_t | bucket_t | bucket_t | bucket_t | … |
---|
- 數組結構 裏面存放 bucket_t 這樣的結構體
- bucket_t 裏面有兩個重要的成員變量 一個是key 另一個IMP
- key 對應OC語言裏面的selector
- IMP 無類型的函數指針
- 根據 key 採用哈希查找算法 在數組中找到對應的bucket_t對象 在數組中的位置 定位位置後就提取bucket_t 中的IMP 來進行函數的調用
class_data_bits_t
- 是objc_class中的成員結構
- class_data_bits_t 主要是對class_rw_t的封裝
- class_rw_t代表了類相關的讀寫信息、對class_ro_t的封裝
- 給類添加的一些分類、方法、屬性和協議 都是封裝在class_rw_t 數據結構中 rw就是讀寫 ro 只讀
- class_ro_t 代表了類相關的只讀信息
class_rw_t
- methods 裏面每個數據塊都是一個數組,數組裏面又有數組,這裏面的單元就是method_t 這個數據結構
- 我們添加的分類A當中的所有的方法都放在第一個數組中
- 分類B同理
- Category 聲明的方法在methods中
class_ro_t
- name 類名 我們可以通過反射來獲取一個類的類名NSClassFromString
- ivars 聲明定義的成員變量
- methodList 是本類中的方法 數據中類型爲method_t