iOS底層原理--isa&類結(jié)構(gòu)探究(文末技術合集參考)

開始探究

本篇開始正式研究類和isa许布,歸根結(jié)底還是圍繞展開探索吧彪。研究類其實無非就是研究isa的走位類的繼承關系這兩個,下面??我們就從isa走位開始進入正題。

本文收錄:<掘金>S_H:isa&類結(jié)構(gòu)探究

準備工作

我們要研究類替蔬,所以首先肯定要需要定義幾個類,這里我們就定義兩個類屎暇,并且他們之間最好有繼承關系承桥,方便后續(xù)探索。

  1. 繼承自NSObject的YSHPerson類
image.png
  1. 繼承自YSHPerson的YSHStudent類
image.png
  1. 在main.m文件中定義兩個對象
image.png

元類

什么是元類根悼?

  1. 以類作為其實例的類凶异。
  2. 元類的定義和創(chuàng)建都是由編譯器完成的。
  3. 對象的isa指向類挤巡,而類其實也是一個對象剩彬,我們可以稱之為類對象,而類對象的isa則指向了元類矿卑。

這么看元類的定義太抽象了喉恋,下面我通過lldb結(jié)合代碼進行分析。

isa走位

由上圖分析母廷,我們大致可以得出isa的走位:

  • 對象的isa指向
  • 類的isa指向元類
  • 元類的isa指向根元類(NSObject)
  • 根元類的isa指向自己

繼承

下面我們來分析一下繼承關系轻黑,我們分為兩種:

  1. 類的繼承關系

我們先寫一個函數(shù),通過信息打印分析一下琴昆。

image.png

通過??的打印信息氓鄙,我們可以看出類的繼承關系:
子類---->父類---->父類的父類---->根類(NSObject)---->nil

image.png

2. 元類的繼承關系

剛才我們分析了類的繼承關系,那我們大膽猜測元類是否也有相應的集成關系呢业舍?老規(guī)矩抖拦,我們還是先寫一個函數(shù),通過信息打印來更加直觀的分析舷暮。

通過??的打印信息蟋座,我們可以看出來元類之間也是存在繼承關系的,但是元類的繼承鏈路和類的繼承鏈路還是有不同的脚牍。特殊之處在根元類(NSObject)最后又繼承了根類(NSObject)
子元類---->父元類---->父元類的父元類---->根元類(NSObject)---->根類(NSObject)---->nil

image.png

isa走位&類繼承總結(jié)

根據(jù)上面的探索分析,我們可以得出來那一份肥腸經(jīng)典的isa&繼承走位圖

isa流程圖.png

isa走位

  • 實例對象(instance of subclass)的isa指向(class)巢墅。
  • 類對象(class)isa指向元類(meta class)诸狭。
  • 元類(meta class)的isa指向根元類(NSObject)(root metal class)券膀。
  • 根元類(NSObject)(root meta class)的isa指向自己本身,形成閉環(huán)驯遇。

繼承關系

  1. 類的繼承
  • (subClass)繼承自父類(superClass)芹彬。
  • 父類(superClass)繼承自根類(NSObject)(rootClass)。
  • 根類(NSObject)繼承自nil叉庐,這也是為什么NSObject是根類舒帮。
  1. 元類的繼承
  • 子類的元類(metal subClass)繼承自父類的元類(metal superClass)。
  • 父類的元類(metal superClass)繼承自根元類(root metal class)陡叠。
  • 根元類(root metal class)繼承自根類(NSObject)(root class)玩郊。

特別注意!M髡蟆R牒臁!兴溜!
不是說OC沒有繼承關系嗎侦厚?此處說的繼承關系是對象的繼承關系,而非拙徽。類是有繼承關系的刨沦。
當然還有哪些不明白的歡迎加入iOS交流群

類的結(jié)構(gòu)分析

內(nèi)存偏移

分析類的結(jié)構(gòu)之前膘怕,我們需要了解內(nèi)存偏移想诅,因為我們想要拿到類的內(nèi)容時,需要通過內(nèi)存偏移去取淳蔼。

  • 普通指針
image.png

打印結(jié)果如下:
image.png

a和b都指向10侧蘸,但是a和b的地址不一樣,地址之間相差4字節(jié)鹉梨,因為a和b都是int類型讳癌。

  • 對象指針
image.png

打印結(jié)果如下:
image.png

p1和p2也是指針,分別指向[YSHPerson alloc]創(chuàng)建的內(nèi)存地址存皂。
&p1和&p2是指向p1和p2對象指針的地址晌坤。

  • 數(shù)組指針

打印結(jié)果如下:
image.png

&c&c[0]取出來的都是首地址。
&c&c[1]相差4個字節(jié)(地址之間差值旦袋,取決于存儲的數(shù)據(jù)類型)
③通過首地址+偏移量可以取出數(shù)組中的元素骤菠,偏移量也就是我們常說的數(shù)組下標。
內(nèi)存中首地址移動的字節(jié)數(shù) = 偏移量 * 數(shù)據(jù)類型字節(jié)數(shù)

類結(jié)構(gòu)探索

通過objc源碼疤孕,我們可以大致知道objc_class內(nèi)部大致有哪些東西商乎,如下圖所示:

ps:因為源碼中有很多方法,對我們用處不大祭阀,這里已省略鹉戚。
image.png

isa:雖然此處注釋了鲜戒,但是objc_class繼承自objc_object,所以objc_class肯定也是有isa的抹凳,占8字節(jié)遏餐。
superclass:Class類型,本質(zhì)是一個結(jié)構(gòu)體指針赢底,占8字節(jié)失都。
cache:是cache_t類型,通過源碼我們可以知道cache_t是結(jié)構(gòu)體類型幸冻,結(jié)構(gòu)體類型的內(nèi)存大小是由其內(nèi)部的屬性來決定的粹庞。
bits:是class_data_bits_t類型,我們無法獲取其具體內(nèi)存大小嘁扼,只能通過我們上面說的內(nèi)存偏移去獲取bits信粮。

  1. cache內(nèi)存大小計算
image.png

我們發(fā)現(xiàn)cache_t是一個結(jié)構(gòu)體,除去static修飾的屬性趁啸,其中影響其內(nèi)存大小的只有??截圖中的兩個:_bucketsAndMaybeMask聯(lián)合體 我們可以得出cache_t這個結(jié)構(gòu)體的內(nèi)存大小為8+8=16字節(jié)强缘。

  1. 獲取bits

在通過內(nèi)存偏移獲取bits內(nèi)容前,我們先看下源碼不傅。
我們底層探索的思路就是:大膽猜測旅掂、小心驗證!!!

我們在源碼中發(fā)現(xiàn)了一個很有意思的結(jié)構(gòu)體class_rw_t,這里面有幾個我們非常熟悉的屬性method_array_t property_array_t property_array_t访娶,不管三七二十一商虐,我先認為屬性、方法存在這里面崖疤,下面??我們正式開始驗證這個大膽的猜測秘车。

  • 屬性列表-property_list

我們首先從屬性列表開始探索,具體分析如下圖所示:

類結(jié)構(gòu)-屬性.png

我們發(fā)現(xiàn)property_list里只有屬性劫哼,沒有成員變量叮趴。那么成員變量又會存在哪里呢?下面我們一步一步探索权烧。
PS:屬性與成員變量的區(qū)別就是有沒有set/get方法眯亦,如果有,則是屬性般码;如果沒有妻率,則是成員變量。

  • 方法列表-methods_list

探索方法列表的方式同屬性列表板祝,lldb具體步驟如下圖所示:
我們會發(fā)現(xiàn)在方法列表里只有實例方法和屬性的set/get方法宫静,并沒有類方法

  • 成員變量-ivars

剛才分析屬性列表時,我們遺留了一個問題,property_list只有屬性囊嘉,那么成員變量存在哪里了呢温技? 通過查看class_rw_t的源碼發(fā)現(xiàn),其中除了methods扭粱、properties、protocols震檩,還有一個ro琢蛤,通過查看class_ro_t源碼,我們發(fā)現(xiàn)其有一個ivar_list_t類型的ivars屬性抛虏。
我們再次做次做出大膽猜測:成員變量是否存儲在這個ivar_list_t類型的ivars屬性中呢博其?下面我們就繼續(xù)小心驗證。
下面??就是lldb步驟:

我們獲取的ivars屬性迂猴,通過打印發(fā)現(xiàn) 成員列表中除了sex慕淡,還有_name_familyName

屬性&成員變量總結(jié)

  • 通過@property聲明的屬性沸毁,存儲在類的bits-->data()-->properties()-->list峰髓,只包含屬性
  • 通過{}聲明的成員變量,存儲在類的bits-->data()-->ro()-->ivars中息尺,除了成員變量携兵,還包括屬性定義的_成員變量
  • 類方法

剛才我們分析methods_list時,也遺留了一個問題搂誉,發(fā)現(xiàn)類的methods里只有實例方法徐紧,并沒有類方法,那么類方法又是存儲在哪里呢炭懊?
在最開始我們分析isa走位的時候并级,提到了元類的概念,元類是用來存儲類的信息的侮腹。 那么我們就又可以大膽猜測了:類方法是否就是存儲在元類的methods_list里呢嘲碧?
下面??是我們進行l(wèi)ldb驗證的步驟:

經(jīng)過我們的層層驗證,發(fā)現(xiàn)我們大膽的猜測都是正確的?Q教丁!??????

實例方法&類方法總結(jié)

  • 類的實例方法存儲在bits-->data()-->methods()-->list至非,其中既包括實例方法钠署,還包括屬性的set/get方法

  • 類的類方法存儲在元類bits-->data()-->methods()-->list荒椭,其中只有類方法谐鼎。

總結(jié)

學習其實就是一個探索的過程中,在實操中一步一步驗證我們的大膽猜測趣惠,這樣的學習方法只有一個壞處狸棍,那就是提升我們對知識的理解程度和加深對知識掌握的印象身害。

文末推薦:iOS熱門文集&視頻解析

① Swift

② iOS底層技術

③ iOS逆向防護

④ iOS面試合集

⑤ 大廠面試題+底層技術+逆向安防+Swift

喜歡的小伙伴記得點贊喔~
收藏等于白嫖,點贊才是真情?( ′???` )?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末草戈,一起剝皮案震驚了整個濱河市塌鸯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌唐片,老刑警劉巖丙猬,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異费韭,居然都是意外死亡茧球,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門星持,熙熙樓的掌柜王于貴愁眉苦臉地迎上來抢埋,“玉大人,你說我怎么就攤上這事督暂【韭ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵损痰,是天一觀的道長福侈。 經(jīng)常有香客問我,道長卢未,這世上最難降的妖魔是什么肪凛? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮辽社,結(jié)果婚禮上伟墙,老公的妹妹穿的比我還像新娘。我一直安慰自己滴铅,他們只是感情好戳葵,可當我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著汉匙,像睡著了一般拱烁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上噩翠,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天戏自,我揣著相機與錄音,去河邊找鬼伤锚。 笑死擅笔,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播猛们,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼念脯,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了弯淘?” 一聲冷哼從身側(cè)響起绿店,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎庐橙,沒想到半個月后惯吕,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡怕午,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了淹魄。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片郁惜。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖甲锡,靈堂內(nèi)的尸體忽然破棺而出兆蕉,到底是詐尸還是另有隱情,我是刑警寧澤缤沦,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布虎韵,位于F島的核電站,受9級特大地震影響缸废,放射性物質(zhì)發(fā)生泄漏包蓝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一企量、第九天 我趴在偏房一處隱蔽的房頂上張望测萎。 院中可真熱鬧,春花似錦届巩、人聲如沸硅瞧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽腕唧。三九已至,卻和暖如春瘾英,著一層夾襖步出監(jiān)牢的瞬間枣接,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工方咆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留月腋,地道東北人。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像榆骚,于是被迫代替她去往敵國和親片拍。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容