iOS的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)

整體Runtime數(shù)據(jù)結(jié)構(gòu)

  • 首先從objc_class這么一個(gè)結(jié)構(gòu)體(數(shù)據(jù)結(jié)構(gòu))開(kāi)始,objc_class繼承于objc_object。
  • objc_object當(dāng)中有一個(gè)成員變量叫isa_t,那么這個(gè)isa_t指針就指向一個(gè)objc_class類型的類對(duì)象(或者說(shuō)元類對(duì)象)。
  • objc_class主要包含三個(gè)成員變量,superClass(指向當(dāng)前類的父類)、cache_t(用來(lái)提供消息傳遞過(guò)程中的緩存方法查找)、class_data_bits_t(類的一些基本信息:類所定義/通過(guò)分類所添加 的成員變量,屬性,方法列表都在這個(gè)數(shù)據(jù)結(jié)構(gòu)中)
    superClass:實(shí)際是class類型的,它指向objc_class類型的這樣一個(gè)指針
    cache_t:實(shí)際上是裝滿了bucket_t數(shù)據(jù)結(jié)構(gòu)的Hash表
    class_data_bits_t:實(shí)際上是對(duì)class_rw_t的數(shù)據(jù)結(jié)構(gòu)的封裝 class_rw_t中包含了(class_ro_t 類相關(guān)的只讀信息、protocols 類分類中的協(xié)議、properties 類分類中的屬性、methods 類分類中的方法)
    class_ro_t包含了name類名、methodList類的方法列表 --method_t、ivars聲明的類的成員變量、類的屬性、類的協(xié)議。

Runtime基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)如下 : objc_object、objc_class、isa指針、method_t

objc_object

即id類型(我們平時(shí)用的所有對(duì)象都是id類型的,在runtime中,id 就是 objc_object結(jié)構(gòu)體)

objc_object結(jié)構(gòu)體主要包含:
1.isa_t:共用體。
2.關(guān)于isa操作相關(guān)的一些方法:通過(guò)objc_object結(jié)構(gòu)體,來(lái)獲取isa所指向的類對(duì)象,或者通過(guò)類對(duì)象的isa指針獲取它的元類對(duì)象一些遍歷的放大。
3.弱引用相關(guān):標(biāo)記一個(gè)對(duì)象是否曾經(jīng)有過(guò)弱引用指針。
4.關(guān)聯(lián)對(duì)象相關(guān)方法:我們?yōu)閷?duì)象設(shè)置了關(guān)聯(lián)屬性,關(guān)于關(guān)聯(lián)屬性的一些相關(guān)方法也體現(xiàn)在objc_object結(jié)構(gòu)體中。
5.內(nèi)存管理相關(guān)的方法實(shí)現(xiàn):MRC下經(jīng)常用到的runtain,release等方法實(shí)現(xiàn) ,以上均封裝在objc_object結(jié)構(gòu)體中。

objc_class

OC中的Class,代表一個(gè)類,他在runtime中對(duì)應(yīng)objc_class的數(shù)據(jù)結(jié)構(gòu)(結(jié)構(gòu)體)。
objc_class繼承objc_object
所以Class這樣一個(gè)類也是一個(gè)對(duì)象,稱為類對(duì)象,因?yàn)樗^承自objc_object。


objc_class包含:
1.objc_class擁有一個(gè)superClass指針,指向class類型,(如果說(shuō)Class是一個(gè)類對(duì)應(yīng)的話,superClass指針指向的就是它的父類對(duì)象,就是我們平時(shí)說(shuō)的類與父類,實(shí)際上是通過(guò)objc_class中superClass成員變量來(lái)定義的)。
2.cache_t cache成員變量: 方法緩存結(jié)構(gòu),消息傳遞時(shí)會(huì)使用這樣的數(shù)據(jù)結(jié)構(gòu)。
3.class_data_bits_t bits數(shù)據(jù)結(jié)構(gòu): 關(guān)于類所定義的變量,屬性,方法都在bits這樣一個(gè)成員結(jié)構(gòu)中。

isa指針

它是C++中的共用體,在OC中名稱是isa_t
不論是64位架構(gòu)上(或者32位架構(gòu))上面,共用體是64個(gè)(或者32個(gè)) 0或者1的數(shù)字 (按大多數(shù)64位分析)

分兩種類型(isa指針是什么含義的時(shí)候):

1.指針型isa: 64位的0或者1的整體內(nèi)容代表所指向的Class的地址,也就是可以通過(guò)isa的內(nèi)容來(lái)獲得類對(duì)象的地址。
2.非指針型isa: isa的值得部分代表Class的地址,之所以這樣是因?yàn)槲覀冊(cè)趯ぶ愤^(guò)程中,只有三四十位數(shù)就可以保證我們尋找到所有Class地址了,多出來(lái)的位可以用來(lái)存儲(chǔ)其他相關(guān)內(nèi)容,來(lái)達(dá)到節(jié)省內(nèi)存的目的。
isa的指向:

關(guān)于對(duì)象,它指向類對(duì)象
例如我們擁有一個(gè)實(shí)例,實(shí)例就是OC中對(duì)應(yīng)的id類型,在Runtime中就是objc_object,里面有個(gè)isa指針,會(huì)指向它對(duì)應(yīng)的Class。

關(guān)于類對(duì)象,指向元類對(duì)象
class因?yàn)榧蒾bjc_object,所以里面也有isa指針,指向其元類對(duì)象。

當(dāng)我們進(jìn)行方法調(diào)用時(shí),調(diào)用一個(gè)實(shí)例的實(shí)例方法,實(shí)際上是通過(guò)isa指針,到它的類對(duì)象中,去進(jìn)行方法查找。
如果我們調(diào)用的是類方法,那么是通過(guò)類對(duì)象的isa指針,到它的元類對(duì)象中去查找。

cache_t

  • 是用于快速查找方法執(zhí)行函數(shù)的一個(gè)結(jié)構(gòu)(當(dāng)我們調(diào)用一個(gè)方法時(shí),如果有緩存,我們就不需要去方法列表中遍歷了,可以提高方法調(diào)用速度)。
  • 是可增量擴(kuò)展的哈希表結(jié)構(gòu)(當(dāng)結(jié)構(gòu)存儲(chǔ)量增大的過(guò)程中, cache_t會(huì)增量擴(kuò)大它的內(nèi)存空間來(lái)支持更多的緩存,用哈希表實(shí)現(xiàn)這個(gè)數(shù)據(jù)結(jié)構(gòu),是為了提高查找效率)。
  • cache_t數(shù)據(jù)結(jié)構(gòu)是計(jì)算機(jī)局部性原理的最佳應(yīng)用(計(jì)算機(jī)局部性原理:在一般調(diào)用方法時(shí),有幾個(gè)方法調(diào)用頻次較高,把他們放到方法緩存中,下次的命中率就會(huì)更高)。

cache_t具體數(shù)據(jù)結(jié)構(gòu)說(shuō)明:


可以理解為是數(shù)組來(lái)實(shí)現(xiàn)的

  • 每個(gè)對(duì)象都是bucket_t這樣的一個(gè)結(jié)構(gòu)體, bucket_t有兩個(gè)主要成員變量,key和IMP。key對(duì)應(yīng)OC中的selector,在調(diào)用方法時(shí)是個(gè)選擇器SEL。
  • IMP理解為無(wú)類型的函數(shù)指針,可以通過(guò)方法選擇器的名稱key來(lái)尋找這個(gè)方法的具體實(shí)現(xiàn)IMP。

假如現(xiàn)在有個(gè)key,可以通過(guò)哈希查找算法來(lái)定位當(dāng)前key所對(duì)應(yīng)的bucket_t位于數(shù)組當(dāng)中哪個(gè)位置,然后從這個(gè)位置中提取出bucket_t中的IMP

class_data_bits_t

這個(gè)結(jié)構(gòu)是objc_class中的成員結(jié)構(gòu)

  • class_data_bits_t主要是對(duì)class_rw_t的封裝。
  • class_rw_t代表了類相關(guān)的讀寫信息,例如給類添加的分類的一些方法,屬性以及協(xié)議等,同時(shí)它也對(duì)class_ro_t的封裝,我們可以隨時(shí)創(chuàng)建分類,為類增加屬性或者方法。rw是readWrite的簡(jiǎn)寫,ro是readOnly的意思,創(chuàng)建類時(shí),添加的成員變量或方法列表在之后就沒(méi)辦法修改了
    class_ro_t代表了類相關(guān)的只讀信息。

class_rw_t

包含
1.class_ro_t
2.protocols類分類中的協(xié)議
3.properties類分類中的屬性
4.methods類分類中的方法
這三個(gè)數(shù)據(jù)結(jié)構(gòu)是個(gè)二維數(shù)組

假如我們?nèi)齻€(gè)分類A、B、C,編譯順序A->B->C。這時(shí)會(huì)逆序遍歷并打包成分類數(shù)組,分類C中的所有方法都在第一列豎列表中,存在二維數(shù)組的第1項(xiàng)。分類B中的所有方法都在第二列豎列表中,存在二維數(shù)組的第2項(xiàng)。分類A中的所有方法都在第三列豎列表中,存在二維數(shù)組的第3項(xiàng)。

     [[method_t,method_t],  [method_t], [method_t,method_t,method_t]]
       -------------------   ----------  -----------------------------
      分類C中的方法列表           B                   A

class_ro_t

1.name:類名
2.ivars:聲明的類的成員變量
3.類的屬性
4.類的協(xié)議
5.類的方法列表
除1外都是一維數(shù)組
在方法列表當(dāng)中存儲(chǔ)的內(nèi)容,一般是分類中添加的方法
method_t實(shí)際上是對(duì)方法的抽象說(shuō)明

method_t

method_t是對(duì)函數(shù)四要素(名稱、返回值、參數(shù)、函數(shù)體)的封裝
函數(shù)四要素決定了函數(shù)的唯一性

method_t是個(gè)結(jié)構(gòu)體,主要有三個(gè)數(shù)據(jù)類型
1.name 函數(shù)名稱
2.types 函數(shù)返回值和參數(shù)的集合
3.imp 無(wú)類型的函數(shù)指針,對(duì)應(yīng)著函數(shù)體

types是如何表示返回值和參數(shù)的

蘋果的Type Encodings技術(shù)
types成員屬性,實(shí)際上表達(dá)結(jié)構(gòu)是:
第一個(gè)位置永遠(yuǎn)是函數(shù)的返回值類型,后面跟著每個(gè)參數(shù)的參數(shù)類型
參數(shù)可以有多個(gè),返回值只有一個(gè)
V@:代表types所存儲(chǔ)的內(nèi)容
V對(duì)應(yīng)返回值,@對(duì)應(yīng)參數(shù)1,:對(duì)應(yīng)參數(shù)2

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容