iOS-底層原理(13)-runtime之isa詳解

序言
  • Objective-C是一門動(dòng)態(tài)性比較強(qiáng)的編程語言,跟C、C++等語言有著很大的不同
  • Objective-C的動(dòng)態(tài)性是由Runtime API來支撐的
  • Runtime API提供的接口基本都是C語言的,源碼由C\C++\匯編語言編寫
位運(yùn)算和共用體
位運(yùn)算

程序中的所有數(shù)在計(jì)算機(jī)內(nèi)存中都是以二進(jìn)制的形式儲(chǔ)存的跨释。位運(yùn)算說穿了侯谁,就是直接對(duì)整數(shù)在內(nèi)存中的二進(jìn)制位進(jìn)行操作洪燥。

C++提供了6種位運(yùn)算符來進(jìn)行位運(yùn)算操作:

  • & 按位與
  • | 按位或
  • ^ 按位異或
  • ~ 按位取反
  • << 左移(左邊消失贾富,右邊補(bǔ)0)
  • >> 右移(右邊消失蓝撇,左邊補(bǔ)符號(hào)位)

位運(yùn)算的操作數(shù)是整數(shù)類型或字符型.

1.按位與&運(yùn)算

相同為一

& 運(yùn)算常常用來將某變量的某些位清0
& 也常用于二進(jìn)制取位操作

2.按位或|運(yùn)算

有一則一

|運(yùn)算通常用于二進(jìn)制特定位上的強(qiáng)制置1

3.按位異或^運(yùn)算

^運(yùn)算通常用于對(duì)二進(jìn)制的特定一位進(jìn)行取反操作

共用體

共用體把幾種不同數(shù)據(jù)類型的變量存放在同一塊內(nèi)存里。共用體中的變量共享同一塊內(nèi)存缭裆。

定義共用體類型變量的一般形式:

union 共用體名
{
    成員列表
}變量列表;

union的主要特征有

  • union中可以定義多個(gè)成員键闺,union的大小由最大的成員的大小決定;
  • union成員共享同一塊大小的內(nèi)存幼驶,一次只能使用其中的一個(gè)成員艾杏;
  • 對(duì)union某一個(gè)成員賦值,會(huì)覆蓋其他成員的值(但前提是成員所占字節(jié)數(shù)相同盅藻,當(dāng)成員所占字節(jié)數(shù)不同時(shí)只會(huì)覆蓋相應(yīng)字節(jié)上的值购桑,比如對(duì)char成員賦值就不會(huì)把整個(gè)int成員覆蓋掉,因?yàn)閏har只占一個(gè)字節(jié)氏淑,而int占四個(gè)字節(jié))勃蜘;
  • union量的存放順序是所有成員都從低地址開始存放的。
一 isa詳解
  • 要想學(xué)習(xí)Runtime假残,首先要了解它底層的一些常用數(shù)據(jù)結(jié)構(gòu)缭贡,比如isa指針
  • 在arm64架構(gòu)之前,isa就是一個(gè)普通的指針辉懒,存儲(chǔ)著Class阳惹、Meta-Class對(duì)象的內(nèi)存地址
  • 從arm64架構(gòu)開始,對(duì)isa進(jìn)行了優(yōu)化眶俩,變成了一個(gè)共用體(union)結(jié)構(gòu)莹汤,還使用位域來存儲(chǔ)更多的信息
image.png
  • isa結(jié)構(gòu)體
/** isa_t 結(jié)構(gòu)體 */
union isa_t {
    Class cls;
    uintptr_t bits;
    struct {
        uintptr_t nonpointer        : 1;
        uintptr_t has_assoc         : 1;
        uintptr_t has_cxx_dtor      : 1;
        uintptr_t shiftcls          : 33;
        uintptr_t magic             : 6;
        uintptr_t weakly_referenced : 1;
        uintptr_t deallocating      : 1;
        uintptr_t has_sidetable_rc  : 1;
        uintptr_t extra_rc          : 19;
    };
};
isa結(jié)構(gòu).png

實(shí)例代碼如下 - 一定需要用真機(jī)進(jìn)行調(diào)試

#import <Foundation/Foundation.h>
@interface CSPerson : NSObject
@end

創(chuàng)建一個(gè)對(duì)象并且斷點(diǎn)調(diào)試,輸出 isa 值

image.png
image.png
image.png
  • 接下來我們創(chuàng)建一些關(guān)聯(lián)對(duì)象和弱引用對(duì)象
image.png
image.png
image.png
image.png
isa參數(shù)詳解
  • nonpointer:
    0颠印,代表普通的指針纲岭,存儲(chǔ)著Class、Meta-Class對(duì)象的內(nèi)存地址
    1线罕,代表優(yōu)化過止潮,使用位域存儲(chǔ)更多的信息

  • has_assoc:是否有設(shè)置過關(guān)聯(lián)對(duì)象,如果沒有钞楼,釋放時(shí)會(huì)更快

  • has_cxx_dtor:是否有C++的析構(gòu)函數(shù)(.cxx_destruct)喇闸,如果沒有,釋放時(shí)會(huì)更快

  • shiftcls:存儲(chǔ)著Class询件、Meta-Class對(duì)象的內(nèi)存地址信息

  • magic:用于在調(diào)試時(shí)分辨對(duì)象是否未完成初始化

  • weakly_referenced:是否有被弱引用指向過仅偎,如果沒有,釋放時(shí)會(huì)更快

  • deallocating:對(duì)象是否正在釋放

  • extra_rc:表示該對(duì)象的引用計(jì)數(shù)值雳殊,實(shí)際上是引用計(jì)數(shù)值減 1橘沥,例如,如果對(duì)象的引用計(jì)數(shù)為 10夯秃,那么 extra_rc 為 9座咆。如果引用計(jì)數(shù)大于 10,則需要使用到下面的 has_sidetable_rc仓洼。

  • has_sidetable_rc:當(dāng)對(duì)象引用計(jì)數(shù)大于 10 時(shí)介陶,則has_sidetable_rc 的值為 1,那么引用計(jì)數(shù)會(huì)存儲(chǔ)在一個(gè)叫 SideTable 的類的屬性中色建,這是一個(gè)散列表哺呜。

為什么要&ISA_MASK來獲取類或元類的地址

因?yàn)閺腶rm64位開始,isa里面存儲(chǔ)各種信息箕戳,是一個(gè)共用體某残,其中shiftcls 33位才是用來存放地址国撵。通過&ISA_MASK就可以將33位的地址值取出來。

無論是實(shí)例對(duì)象玻墅,還是類對(duì)象介牙,還是元類對(duì)象,他們的地址最后一位要么是0澳厢,要么是8环础,因?yàn)樗麄兊牡刂肥?code>isa & ISA_MASK,又因?yàn)?code>ISA_MASK最后3位都是0剩拢,所以導(dǎo)致他們的地址最后3位也永遠(yuǎn)是0线得,所以最后一位要么是0(0000 0000),要么是8(0000 1000)徐伐。


本文主要參考MJ老師的教案贯钩,非常感謝MJ老師。

項(xiàng)目連接地址 - runtime_union_mask


關(guān)于runtime更多文章請看如下鏈接
iOS-runtime-API詳解+使用
iOS Runtime原理及使用
iOS - runtime如何通過selector找到對(duì)應(yīng)的 IMP地址(分別考慮類方法和實(shí)例方法)
iOS - Runtime之面試題詳解一
iOS-runtime之面試題詳解二
iOS runtime的使用場景-實(shí)戰(zhàn)篇

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末呵晨,一起剝皮案震驚了整個(gè)濱河市魏保,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌摸屠,老刑警劉巖谓罗,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異季二,居然都是意外死亡檩咱,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門胯舷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刻蚯,“玉大人,你說我怎么就攤上這事桑嘶〈缎冢” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵逃顶,是天一觀的道長讨便。 經(jīng)常有香客問我,道長以政,這世上最難降的妖魔是什么霸褒? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮盈蛮,結(jié)果婚禮上废菱,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好殊轴,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布衰倦。 她就那樣靜靜地躺著,像睡著了一般梳凛。 火紅的嫁衣襯著肌膚如雪耿币。 梳的紋絲不亂的頭發(fā)上梳杏,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天韧拒,我揣著相機(jī)與錄音,去河邊找鬼十性。 笑死叛溢,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的劲适。 我是一名探鬼主播楷掉,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼霞势!你這毒婦竟也來了烹植?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤愕贡,失蹤者是張志新(化名)和其女友劉穎草雕,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體固以,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡墩虹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了憨琳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诫钓。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖篙螟,靈堂內(nèi)的尸體忽然破棺而出菌湃,到底是詐尸還是另有隱情,我是刑警寧澤遍略,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布惧所,位于F島的核電站,受9級(jí)特大地震影響墅冷,放射性物質(zhì)發(fā)生泄漏纯路。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一寞忿、第九天 我趴在偏房一處隱蔽的房頂上張望驰唬。 院中可真熱鬧,春花似錦、人聲如沸叫编。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽搓逾。三九已至卷谈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間霞篡,已是汗流浹背世蔗。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留朗兵,地道東北人污淋。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像余掖,于是被迫代替她去往敵國和親寸爆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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