iOS底層原理--Runtime isa

runtime簡(jiǎn)介

運(yùn)行時(shí)(Runtime)是指將數(shù)據(jù)類型的確定由編譯時(shí)推遲到了運(yùn)行時(shí),Runtime是一套比較底層的純C語言API, 屬于1個(gè)C語言庫, 包含了很多底層的C語言API,平時(shí)編寫的OC代碼柑船,在程序運(yùn)行過程中,其實(shí)最終會(huì)轉(zhuǎn)換成Runtime的C語言代碼轻要,Runtime是Object-C的幕后工作者,Object-C會(huì)使用到Runtime來創(chuàng)建類和對(duì)象,進(jìn)行消息發(fā)送和轉(zhuǎn)發(fā)

特性: 編寫的代碼具有運(yùn)行時(shí)某残、動(dòng)態(tài)特性

isa
在我們初窺oc對(duì)象的時(shí)候了解到了isa,開始的時(shí)候我們感覺它像是一個(gè)C的指針陵吸,現(xiàn)在我們想要細(xì)致的了解iOS的運(yùn)行時(shí)機(jī)制玻墅,我們需要更加細(xì)致的了解isa,對(duì)于我們了解runtime有很大的幫助壮虫。

arm64之前澳厢,isa只是一個(gè)指針,保存對(duì)象地址或者類對(duì)象地址,但是在arm64架構(gòu)之后剩拢,蘋果對(duì)isa進(jìn)行了優(yōu)化线得,變成了一個(gè)union結(jié)構(gòu),通過位域方式來存儲(chǔ)更多的信息裸扶。

共用體:在進(jìn)行某些算法的C語言編程的時(shí)候框都,需要使幾種不同類型的變量存放到同一段內(nèi)存單元中。也就是使用覆蓋技術(shù)呵晨,幾個(gè)變量互相覆蓋。這種幾個(gè)不同的變量共同占用一段內(nèi)存的結(jié)構(gòu)熬尺,在C語言中摸屠,被稱作“共用體”類型結(jié)構(gòu),簡(jiǎn)稱共用體粱哼。

先看下objc_object源碼

我們知道OC對(duì)象的isa指針并不是直接指向類對(duì)象或者元類對(duì)象季二,而是需要&ISA_MASK通過位運(yùn)算才能獲取到類對(duì)象或者元類對(duì)象的地址。今天來探尋一下為什么需要&ISA_MASK才能獲取到類對(duì)象或者元類對(duì)象的地址揭措,以及這樣的好處胯舷。源碼中isa_t是union類型, 可以看到共用體中有一個(gè)結(jié)構(gòu)體,結(jié)構(gòu)體內(nèi)部分別定義了一些變量绊含,變量后面的值代表的是該變量占用多少個(gè)二進(jìn)制位桑嘶,也就是位域技術(shù)。

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ǔ)更多的信息

union isa_t {
    isa_t() { }
    isa_t(uintptr_t value) : bits(value) { }

    Class cls;
    uintptr_t bits;
#if defined(ISA_BITFIELD)
    struct {
        ISA_BITFIELD;  // defined in isa.h
    };
#endif
};

# if __arm64__
#   define ISA_MASK        0x0000000ffffffff8ULL
#   define ISA_MAGIC_MASK  0x000003f000000001ULL
#   define ISA_MAGIC_VALUE 0x000001a000000001ULL
#   define ISA_BITFIELD                                                      \
      uintptr_t nonpointer        : 1;                                       \
      uintptr_t has_assoc         : 1;                                       \
      uintptr_t has_cxx_dtor      : 1;                                       \
      uintptr_t shiftcls          : 33; /*MACH_VM_MAX_ADDRESS 0x1000000000*/ \
      uintptr_t magic             : 6;                                       \
      uintptr_t weakly_referenced : 1;                                       \
      uintptr_t deallocating      : 1;                                       \
      uintptr_t has_sidetable_rc  : 1;                                       \
      uintptr_t extra_rc          : 19
#   define RC_ONE   (1ULL<<45)
#   define RC_HALF  (1ULL<<18)

# elif __x86_64__
#   define ISA_MASK        0x00007ffffffffff8ULL
#   define ISA_MAGIC_MASK  0x001f800000000001ULL
#   define ISA_MAGIC_VALUE 0x001d800000000001ULL
#   define ISA_BITFIELD                                                        \
      uintptr_t nonpointer        : 1;                                         \
      uintptr_t has_assoc         : 1;                                         \
      uintptr_t has_cxx_dtor      : 1;                                         \
      uintptr_t shiftcls          : 44; /*MACH_VM_MAX_ADDRESS 0x7fffffe00000*/ \
      uintptr_t magic             : 6;                                         \
      uintptr_t weakly_referenced : 1;                                         \
      uintptr_t deallocating      : 1;                                         \
      uintptr_t has_sidetable_rc  : 1;                                         \
      uintptr_t extra_rc          : 8
#   define RC_ONE   (1ULL<<56)
#   define RC_HALF  (1ULL<<7)

# else
#   error unknown architecture for packed isa
# endif

可以簡(jiǎn)化為下面的圖


image.png

這里我們了解下每個(gè)字段的意義
nonpointer 代表iOS是普通的指針,存儲(chǔ)著Class技矮、Meta-Class對(duì)象的內(nèi)存地址代表優(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 里面存儲(chǔ)的值是引用計(jì)數(shù)器減1
has_sidetable_rc 引用計(jì)數(shù)器是否過大無法存儲(chǔ)在isa中如果為1,那么引用計(jì)數(shù)會(huì)存儲(chǔ)在一個(gè)叫SideTable的類的屬性中

isa需求

isa取值

00000101
&00000100
·-------------
00000100
isa進(jìn)行&操作十性,取哪位哪位值為1叛溢,結(jié)果有值相應(yīng)位為1無值為0

補(bǔ)充“>>”代表左移 ,例“1>>0”左移0位 0b000001 值位1 劲适,“1>>1左移1位 0b000010 值位2

isa取值

使用||操作楷掉,和&操作
設(shè)置位賦值為1

設(shè)置位賦值為1,先安位取反 00000100 = ~111101111霞势,在安位&烹植,

取反產(chǎn)操作“~”

00000101
&11111011
·-------------
00000001

isa位域

    // 位域技術(shù),利用了每個(gè)字節(jié)的每一位
    struct {
        char tall : 1; 
        char rich : 1;
        char handsome : 1;
    } _tallRichHandsome; 一個(gè)

補(bǔ)充共用體
在進(jìn)行某些算法的C語言編程的時(shí)候愕贡,需要使幾種不同類型的變量存放到同一段內(nèi)存單元中草雕。也就是使用覆蓋技術(shù),幾個(gè)變量互相覆蓋固以。這種幾個(gè)不同的變量共同占用一段內(nèi)存的結(jié)構(gòu)墩虹,在C語言中,被稱作“共用體”類型結(jié)構(gòu)憨琳,簡(jiǎn)稱共用體诫钓,也叫聯(lián)合體,用isa舉例子:isa所有數(shù)據(jù)都存在bits里面,下面的結(jié)構(gòu)體是用于理解的

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子评凝,更是在濱河造成了極大的恐慌渔隶,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)纯路,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寞忿,“玉大人驰唬,你說我怎么就攤上這事∏徽茫” “怎么了叫编?”我有些...
    開封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)霹抛。 經(jīng)常有香客問我搓逾,道長(zhǎng),這世上最難降的妖魔是什么杯拐? 我笑而不...
    開封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任霞篡,我火速辦了婚禮世蔗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘朗兵。我一直安慰自己污淋,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開白布余掖。 她就那樣靜靜地躺著寸爆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪盐欺。 梳的紋絲不亂的頭發(fā)上赁豆,一...
    開封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音找田,去河邊找鬼歌憨。 笑死,一個(gè)胖子當(dāng)著我的面吹牛墩衙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播甲抖,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼漆改,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了准谚?” 一聲冷哼從身側(cè)響起挫剑,我...
    開封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎柱衔,沒想到半個(gè)月后樊破,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡唆铐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年哲戚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片艾岂。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡顺少,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出王浴,到底是詐尸還是另有隱情脆炎,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布氓辣,位于F島的核電站秒裕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏钞啸。R本人自食惡果不足惜几蜻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一喇潘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧入蛆,春花似錦响蓉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至扼褪,卻和暖如春想幻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背话浇。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工脏毯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人幔崖。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓食店,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親赏寇。 傳聞我的和親對(duì)象是個(gè)殘疾皇子吉嫩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

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