Class的結構

Class的結構

image.png

class_rw_t

class_rw_t里面的methods弟灼、properties、protocols是二維數(shù)組,是可讀可寫的惫企,包含了類的初始內容、分類的內容


image.png

class_ro_t

class_ro_t里面的baseMethodList陵叽、baseProtocols雅任、ivars、baseProperties是一維數(shù)組咨跌,是只讀的,包含了類的初始內容

image.png

底層運行邏輯:編寫代碼運行后,開始類的方法,成員變量 屬性 協(xié)議等信息都存放在 const class_ro_t中,運行過程中,會將信息整合,動態(tài)創(chuàng)建 class_rw_t,然后會將 class_ro_t中的內容(類的原始信息:方法 屬性 成員變量 協(xié)議信息) 和 分類的方法 屬性 協(xié)議 成員變量的信息 存儲到 class_rw_t中.并通過數(shù)組進行排序,分類方法放在數(shù)組的前端,原類信息放在數(shù)組的后端.運行初始 objc-class中的 bits是指向 class_ro_t的,bits中的data取值是從class_ro_t中獲得,而后創(chuàng)建 class_rw_t,class_rw_t中的 class_ro_t從初始的 class_ro_t中取值,class_rw_t初始化完成后,修改 objc_class中的bits指針指向class_rw_t

method_t

  • method_t是對方法\函數(shù)的封裝


    image.png
  • IMP代表函數(shù)的具體實現(xiàn)
    typedef id _Nullable (*IMP)(id _Nonnull,SEL _Nonnull,...);
  • SEL代表方法\函數(shù)名硼婿,一般叫做選擇器锌半,底層結構跟char *類似
  • 可以通過@selector()和sel_registerName()獲得
  • 可以通過sel_getName()和NSStringFromSelector()轉成字符串
  • 不同類中相同名字的方法,所對應的方法選擇器是相同的
    typedef struct objc_selector *SEL;

types包含了函數(shù)返回值寇漫、參數(shù)編碼的字符串

返回值 參數(shù)1 參數(shù)2 ... 參數(shù)n

Type Encoding

iOS中提供了一個叫做@encode的指令刊殉,可以將具體的類型表示成字符串編碼


image.png

方法緩存

Class內部結構中有個方法緩存(cache_t),用散列表(哈希表)來緩存曾經調用過的方法州胳,可以提高方法的查找速度.


image.png

緩存查找:

-objc-cache.mm

  • bucket_t * cache_t::find(cache_key_t k, id receiver)

cache_t cache : Class內部結構有個方法緩存(cache_t),用散列表來緩存曾經調用過的方法,可以提高方法的查找速度.

LDPerson *person = [[LDPerson alloc] init]
[person test]

消息機制:

思路:test方法為對象方法,存儲在class對象當中.所以首先會通過instanceisa指針查找到LDPersonclass對象,然后去cache方法緩存列表中查找是否有該方法的緩存,如果有直接調用,如果沒有進行下面的操作

然后找到class對象中的 methodList(方法列表)進行遍歷查找該方法,如果查找到該方法,調用該方法,并添加到方法緩存cache中,方便下次調用,省略再次調用遍歷方法列表(二維數(shù)組)的操作,如果在該class對象中沒有找到該方法,會通過該class對象的superClasss指針查找到class對象的父類 superClass,再查找到superClasscache方法緩存列表,如果緩存中沒有該方法,則會通過bits --> class_rw_t --->methodList,進行遍歷操作,沿構造鏈一直向上查找,查找到最底層的baseClass類,如果還沒找到該方法,就會拋出異常,該方法找不到的錯誤.

注意:類初始化后,第一次調用某方法時就會將方法添加到緩存列表cache中,二次及以后調用時,會優(yōu)先去cache中查找是否有該方法的緩存,如果有直接調用,如果沒有重復上述操作.子類對象第一次調用父類方法時,會通過isa指針向上查找,查找到父類方法后會將該父類方法添加到自己的方法緩存列表中,下次調用時,就不需要superClass指針查找父類方法了!

cache散列表實現(xiàn)原理:

通過struct bucket_t結構體中的兩個成員變量:cache_key_t _key(SEL作為key)imp _imp(函數(shù)指針,指向函數(shù)的地址)例如:

LDPerson *person = [[LDPerson alloc] init]
[person test]

@selector(test) & _mask 通過SEL和結構體cache_t中的_mask做與運算,得到一個值,這個值就是該方法testcache_t結構體數(shù)組 _buckets(方法緩存列表)中的索引.當test方法第一次被調用時,通過sel&_mask得到該方法索引,并將該方法存儲到方法緩存數(shù)組的索引位置.當先次調用該方法時,會有優(yōu)先去方法緩存列表中尋找_mask,通過該方法的SEL&_mask得到該方法索引位置,然后通過該索引去_buckets列表中去查找該方法,如果為空,則遍歷LDPersonclass對象的方法列表(加入_caches緩存列表,如果沒有沿構造鏈向上尋找...).如果多個方法的SEL&_mask得到的索引相等,即該索引位置已經存儲過方法,則將得到的索引位置減1,作為該方法的索引位置.如果減一后的索引位置還是被占用,最終會讓索引值等于Mask,當_buckets緩存列表數(shù)組需要擴容時,每次擴容都是當前容量的二倍.擴容時會充值_mask的值!因為_mask被重置,方法SEL&_mask的索引位置發(fā)生變化,已經無法正確獲取到該方法的緩存索引,所以_buckets會清空緩存,重新開始計算索引位置并緩存方法.

哈希表的核心原理: f(key) == index,通過一個函數(shù)算法(求余或與運算 或其他運算),傳入一個作為查找的KEY的得到一個索引位置,如果該索引位置被占用,則可進行其他運算,直到得到一個不被占用的位置.(Apple通過減一操作獲取新索引,如果減一到索引0的位置還是被占用,則設置索引位置為_mask,如果還是被占用則進行_mask減一操作,如果都被占用進行擴容操作)并將目標存到該索引位置,就是哈希表的核心原理!

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末记焊,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子栓撞,更是在濱河造成了極大的恐慌遍膜,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓤湘,死亡現(xiàn)場離奇詭異瓢颅,居然都是意外死亡,警方通過查閱死者的電腦和手機弛说,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進店門挽懦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人木人,你說我怎么就攤上這事信柿〖脚迹” “怎么了?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵渔嚷,是天一觀的道長进鸠。 經常有香客問我,道長圃伶,這世上最難降的妖魔是什么堤如? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮窒朋,結果婚禮上搀罢,老公的妹妹穿的比我還像新娘。我一直安慰自己侥猩,他們只是感情好榔至,可當我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著欺劳,像睡著了一般唧取。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上划提,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天枫弟,我揣著相機與錄音,去河邊找鬼鹏往。 笑死淡诗,一個胖子當著我的面吹牛,可吹牛的內容都是我干的伊履。 我是一名探鬼主播韩容,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼唐瀑!你這毒婦竟也來了群凶?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤哄辣,失蹤者是張志新(化名)和其女友劉穎请梢,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體力穗,經...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡溢陪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了睛廊。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片形真。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出咆霜,到底是詐尸還是另有隱情邓馒,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布蛾坯,位于F島的核電站光酣,受9級特大地震影響,放射性物質發(fā)生泄漏脉课。R本人自食惡果不足惜救军,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望倘零。 院中可真熱鬧唱遭,春花似錦、人聲如沸呈驶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽袖瞻。三九已至司致,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間聋迎,已是汗流浹背脂矫。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留霉晕,地道東北人羹唠。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像娄昆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子缝彬,可洞房花燭夜當晚...
    茶點故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內容