iOS筆記 ___ Runtime相關(guān)問(wèn)題

1、什么是runtime

runtime又叫運(yùn)行時(shí)拍屑,將數(shù)據(jù)類型的確定由編譯時(shí)推遲到了運(yùn)行時(shí) 是一套比較底層的純C語(yǔ)言API??OC代碼在運(yùn)行過(guò)程中會(huì)被轉(zhuǎn)成runtime的C語(yǔ)言代碼途戒,可以用于在程序的運(yùn)行過(guò)程中動(dòng)態(tài)的創(chuàng)建類,??動(dòng)態(tài)添加、修改類的方法和屬性負(fù)責(zé)消息的傳遞和轉(zhuǎn)發(fā)查找類中的成員僵驰、屬性喷斋、方法

2、Runtime的數(shù)據(jù)模型是怎樣的

主要objc_object蒜茴、 objc_class星爪、 isa指針、 method_t 幾個(gè)重要部分組成

objc_object:

平時(shí)我們所使用的所有對(duì)象都是ID類型的粉私, ID類型的對(duì)象對(duì)應(yīng)到runtime當(dāng)中實(shí)際上代表的就是objc_object結(jié)構(gòu)體 主要包含

isa_t (共用體)

關(guān)于isa指針操作 (比如通過(guò)objc_objec這個(gè)結(jié)構(gòu)體獲取它的isa所指向的類對(duì)象顽腾,包括類對(duì)象的isa指針指向的元類對(duì)象)

弱引用相關(guān)的方法 (比如標(biāo)記一個(gè)對(duì)象是否有弱引用指針)

關(guān)聯(lián)對(duì)象相關(guān)的方法 (比如這個(gè)對(duì)象我們?yōu)樗O(shè)置了關(guān)聯(lián)屬性, 關(guān)聯(lián)對(duì)象的一些方法也體現(xiàn)在objc_object)

內(nèi)存管理 (retain/release/autoreleasePool)

objc_class:

在OC語(yǔ)言當(dāng)中所使用的Class 對(duì)應(yīng)到runtime當(dāng)中就是objc_class 它也是一個(gè)結(jié)構(gòu)體

objc_class繼承自objc_object, objc_object中的isa指針指向objc_class類對(duì)象或元類對(duì)象

objc_class 由 superClass诺核、 cache_t抄肖、 class_data_bits_t 3個(gè)結(jié)構(gòu)體組成

superClass指針:指向的類型也是一個(gè)Class,如果是類對(duì)象則指向當(dāng)前類的父類

cache_t: 主要用于消息傳遞當(dāng)中緩存方法的查找窖杀, 對(duì)應(yīng)了裝滿bucket_t數(shù)據(jù)結(jié)構(gòu)的哈希表

class_data_bits_t: 它是對(duì)class_rw_t結(jié)構(gòu)體的一層封裝漓摩,主要用于表達(dá)類的基本信息,比如成員變量入客、屬性管毙、方法列表 包括分類的添加

class_rw_t: 代表了類相關(guān)的讀寫(xiě)信息 是對(duì)class_ro_t的一層封裝, 主要包含了

class_ro_t

properites

procotols

methods

class_ro_t:這個(gè)結(jié)構(gòu)體中包含了

name

ivar

properites

procotols

methodList

isa指針:

在oc當(dāng)中命名為isa_t共用體 是C++類型的空用體

指針類isa: isa的值代表Class地址

非指針型isa: isa的值部分代表Class地址

如果是對(duì)象則指向其類對(duì)象, 如果是類對(duì)象則指向其元類對(duì)象

實(shí)例 ---- isa ---- class

CLass --- isa ---- MetaClass

method_t:

1

2

3

3痊项、cache_t的作用是什么锅风, 具有什么特點(diǎn)

在消息傳遞的過(guò)程中用于快速查找方法執(zhí)行函數(shù),如果有一個(gè)緩存就不用到它的方法列表中去查找鞍泉,可以提高消息傳遞效率

是可增量擴(kuò)展的哈希表結(jié)構(gòu) //當(dāng)我們存儲(chǔ)的這個(gè)結(jié)構(gòu)增大會(huì)逐漸的增大內(nèi)存空間

是局部性原理的最佳應(yīng)用

4皱埠、什么是 bucket_t (KEY IMP),如何定位bucket_t 如何進(jìn)行緩存查找

bucket_t是以哈希表方式存儲(chǔ)方法列表的,??通過(guò)key->value直接進(jìn)行訪問(wèn)的數(shù)據(jù)結(jié)構(gòu)

以SEL為key咖驮,_imp為value來(lái)存儲(chǔ)方法?

它通過(guò)把關(guān)鍵碼值映射到表中一個(gè)位置來(lái)訪問(wèn)記錄边器,以加快查找的速度

5训枢、類對(duì)象、元類對(duì)象分別是什么

類對(duì)象與元類對(duì)象都是objc_class數(shù)據(jù)結(jié)構(gòu)的忘巧,這個(gè)數(shù)據(jù)結(jié)構(gòu)繼承了objc_object所有他們都有isa指針

類對(duì)象存儲(chǔ)實(shí)例方法列表等信息恒界,??

元類對(duì)象存儲(chǔ)類表方列表法等信息??

6、如何找到類對(duì)象元類對(duì)象

實(shí)例對(duì)象可以通過(guò)isa指針找到它的類對(duì)象

類對(duì)象可以通過(guò)isa指針找到它的元類對(duì)象

7砚嘴、元類對(duì)象的指針指向哪里

????1十酣、任何一個(gè)元類對(duì)象它的isa指針都指向根元類對(duì)象

8、如果我們調(diào)用的類方法沒(méi)有實(shí)現(xiàn) 但是有同名的實(shí)例方法實(shí)現(xiàn)會(huì)不會(huì)產(chǎn)生崩潰或?qū)嶋H調(diào)用

不會(huì)奔潰

由于根元類對(duì)象的superClass指針指向了根類對(duì)象际长,當(dāng)我們?cè)谠悓?duì)象找類方找不到的時(shí)候會(huì)逐級(jí)向上查找 如果有同名的實(shí)例方法會(huì)調(diào)用

9耸采、class是否是對(duì)象?? ? ? ? ? ??

Class是對(duì)象,我們稱為類對(duì)象

在OC語(yǔ)言當(dāng)中所使用的Class 對(duì)應(yīng)到runtime當(dāng)中就是objc_class 它也是一個(gè)結(jié)構(gòu)體 工育,objc_class 繼承自 objc_object

10虾宇、***?消息傳遞的過(guò)程 ?

首先調(diào)用方法的時(shí)候會(huì)使用哈希方法查找 緩存中是否命中,看看緩存中是否有對(duì)應(yīng)的選擇器名稱的方法實(shí)現(xiàn)如绸,如果有就通過(guò)函數(shù)指針調(diào)用函數(shù)

如果沒(méi)有則通過(guò)當(dāng)前實(shí)例的isa指針查找當(dāng)前類對(duì)象的方法列表嘱朽,如果找到則根據(jù)函數(shù)指針進(jìn)行調(diào)用 (如果方法列表已排序則使用二分查找,如果沒(méi)有排序則使用遍歷查找)

如果在當(dāng)前類對(duì)象方法列表中沒(méi)有找到就會(huì)逐級(jí)在父類方法列表中查找

如果在父類方法中一直查到根類還沒(méi)有找到怔接,就會(huì)進(jìn)入消息轉(zhuǎn)發(fā)流程

12搪泳、***?什么是緩存查找,如何進(jìn)行緩存查找扼脐,什么是哈希查找?

在消息傳遞的過(guò)程中用于快速查找方法執(zhí)行函數(shù)森书,如果有一個(gè)緩存就不用到它的方法列表中去查找,可以提高消息傳遞效率

緩存查找就是根據(jù)選擇器因子到緩存哈希表中(cache_t)射出bucket_t在數(shù)組中的位置 找到bucket_t位置提取出imp指針?lè)祷亟o調(diào)用方

通過(guò)我們給定的一個(gè)值經(jīng)過(guò)哈希函數(shù)的算法 算出的這個(gè)值就是bucket_t在數(shù)組中的索引位置

11谎势、在當(dāng)前類中如果查找方法

對(duì)于沒(méi)有排序好的列表凛膏,采用“遍歷方法”查找執(zhí)行函數(shù)

對(duì)于已排序好的列表采用“二分查找”算法查找方法的對(duì)應(yīng)執(zhí)行函數(shù)

12、話一副消息傳遞流程圖

13脏榆、objc_msgSend objc_msgSuperSend有什么區(qū)別

objc_msgSend:

OC的方法調(diào)用:消息機(jī)制,給方法調(diào)用者發(fā)送消息

objc_msgSend會(huì)根據(jù)在信息在對(duì)象isa指針指向的Class中尋找該SEL對(duì)應(yīng)的IMP猖毫,從而完成方法的調(diào)用

任意的OC方法的調(diào)用,比如[obj aMethod]都會(huì)被翻譯成objc_msgSend()

由此進(jìn)入objc_msgSend執(zhí)行

objc_msgSuperSend:

消息轉(zhuǎn)發(fā)會(huì)調(diào)用 objc_msgSendSuper

告訴系統(tǒng)去父類方法列表里面去找但是調(diào)用者主體還是self

super只是一個(gè)編譯器的特殊字符须喂,并不代表父類的一個(gè)實(shí)例化對(duì)象

14吁断、*** 消息的轉(zhuǎn)發(fā)流程是怎樣的

首先 實(shí)例方法的轉(zhuǎn)發(fā)流程會(huì)調(diào)用:resolveInstanceMethod, 類方法的轉(zhuǎn)發(fā)流程會(huì)調(diào)用resolveClassMethod (它是一個(gè)類方法返回值是BOOL 返回值是一個(gè)BOOL告訴系統(tǒng)我們要不要解決當(dāng)前實(shí)例方法的實(shí)現(xiàn) 如果返回YES相當(dāng)于通知系統(tǒng)當(dāng)前消息已經(jīng)處理接觸了消息轉(zhuǎn)發(fā)流程)

如果是NO 系統(tǒng)會(huì)給予我們第二次機(jī)會(huì)處理這條消息會(huì)執(zhí)行 forwardingTargetForselector 這個(gè)方法(這個(gè)方法的返回值是id相當(dāng)于告訴系統(tǒng)這個(gè)方法的調(diào)用應(yīng)該由哪個(gè)對(duì)象來(lái)處理 轉(zhuǎn)發(fā)對(duì)象是誰(shuí) 如果指定了轉(zhuǎn)發(fā)目標(biāo)系統(tǒng)會(huì)把結(jié)果返回給轉(zhuǎn)發(fā)目標(biāo)并結(jié)束消息轉(zhuǎn)發(fā)流程)

如果在沒(méi)有轉(zhuǎn)發(fā)目標(biāo)的情況下,系統(tǒng)會(huì)給我們最后一次會(huì)??調(diào)用methodSingnatureForSelector這個(gè)方法 返回值是NSmethodSignature對(duì)象(這個(gè)對(duì)象是實(shí)際是對(duì)方法選擇器返回類的類型)

如果返回了方法簽名系統(tǒng)會(huì)返回forwardInvocation: 如果forwardInvocation能夠處理則流程結(jié)束 如果NSMethodSignature返回空 則消息無(wú)法處理

15坞生、什么是Method-Swizzling, 一般會(huì)用到哪里

Method-Swizzling 又叫方法混淆仔役,簡(jiǎn)單說(shuō)就是進(jìn)行方法交換 主要用來(lái)修改selector對(duì)應(yīng)的IMP實(shí)現(xiàn)

首先倒入runtime頭文件

通過(guò)class_getClassMethod 獲取方法結(jié)構(gòu)體method

通過(guò)method_exchangeImplementations 進(jìn)行方法交換

實(shí)現(xiàn)方法

新方法替換老方法

頁(yè)面進(jìn)出添加統(tǒng)計(jì)信息

數(shù)組越界 空值導(dǎo)致的崩潰問(wèn)題

是unrecognized selector sent to class會(huì)導(dǎo)致APP崩潰

16、是否使用過(guò)performSelector

在動(dòng)態(tài)添加方法的時(shí)候使用是己,一個(gè)類在編譯時(shí)候沒(méi)有這個(gè)方法又兵,在運(yùn)行時(shí)才產(chǎn)生了這個(gè)方法 在此場(chǎng)景下需要調(diào)用performSelector

class_addMethod(self, @selector(test), testImp, "v@:"); 方法添加

void testImp(void) {NSLog(@"test invoke");}


17、在什么場(chǎng)景下需要?jiǎng)討B(tài)添加方法

?如果一個(gè)類方法非常多,加載類到內(nèi)存的時(shí)候也比較耗費(fèi)資源沛厨,需要給每個(gè)方法生成映射表宙地,可以使用動(dòng)態(tài)給某個(gè)類,添加方法解決

18逆皮、什么是動(dòng)態(tài)方法解析

使用@dynamic關(guān)鍵字進(jìn)行修飾

當(dāng)我們把屬性編修飾為@dynamic時(shí)代表著不需要編譯器為我們生成getter setter的具體實(shí)現(xiàn)

在運(yùn)行時(shí)具體的調(diào)用了getter setter的時(shí)候在去為它添加具體的實(shí)現(xiàn)宅粥,只有動(dòng)態(tài)運(yùn)行時(shí)語(yǔ)言才支持這種功能

19、編譯時(shí)語(yǔ)言與動(dòng)態(tài)運(yùn)行時(shí)語(yǔ)言的區(qū)別电谣, 動(dòng)態(tài)進(jìn)行時(shí)語(yǔ)言有什么優(yōu)點(diǎn)

動(dòng)態(tài)運(yùn)行時(shí)語(yǔ)言將函數(shù)決議由編譯時(shí)推遲到運(yùn)行時(shí) 實(shí)際上就是在運(yùn)行時(shí)為方法添加具體執(zhí)行函數(shù)

編譯時(shí)語(yǔ)言它是在編譯器進(jìn)行函數(shù)決議秽梅,在編譯期間一個(gè)方法名稱所對(duì)應(yīng)的函數(shù)執(zhí)行體是哪個(gè) 在具體運(yùn)行過(guò)程中不能被修改

我們寫(xiě)代碼時(shí)更具靈活性,如我們可以把消息轉(zhuǎn)發(fā)給我們想要的對(duì)象剿牺,或者隨意交換一個(gè)方法的實(shí)現(xiàn)等

20风纠、*** [obj foo]和 objc_msgSend()函數(shù)之間有什么關(guān)系

[obj foo]在編譯器處理后就變成了 objc_msgSend函數(shù)調(diào)用 然后開(kāi)始了runtime的消息傳遞過(guò)程

第一參數(shù)是obj

第二個(gè)參數(shù)是foo選擇器

由于這個(gè)方法沒(méi)有其他桉樹(shù)所以objc_msgSend的餐食只有兩個(gè)

21、runtime如果通過(guò)selector 找到IMP地址 (或者回答消息傳遞機(jī)制)

緩存是否命中

當(dāng)前類方法列表是否命中 (二分查找牢贸,遍歷查找)

逐級(jí)父類方法是否命中 (根據(jù)superClass a, b)

22、能否為編譯后的類中添加實(shí)例變量(注意是編譯后镐捧,還是動(dòng)態(tài)添加)

????1潜索、不可以,因?yàn)榫幾g之前創(chuàng)建的類已經(jīng)完成了變量的布局懂酱, class_ro_t 在編譯后無(wú)法進(jìn)行修改

23竹习、能否為動(dòng)態(tài)添加的類中添加實(shí)例變量????

????1、可以列牺,因?yàn)槲议T在動(dòng)態(tài)添加的類的過(guò)程中只要在它調(diào)用注冊(cè)類隊(duì)之前完成實(shí)例變量的添加就可以實(shí)現(xiàn)

24整陌、***runtime 如何實(shí)現(xiàn) weak 屬性

? ?weak的特點(diǎn):

weak策略表明該屬性定義了一種“非擁有關(guān)系” (nonowning relationship)

為這種屬性設(shè)置新值時(shí),設(shè)置方法既不保留新值瞎领,也不釋放舊值

此特質(zhì)同assign類似;然而在屬性所指的對(duì)象遭到摧毀時(shí)泌辫,屬性值也會(huì)清空(nil out)

? ? runtime 如何實(shí)現(xiàn) weak 變量的自動(dòng)置nil:

runtime 對(duì)注冊(cè)的類會(huì)進(jìn)行布局,對(duì)于weak對(duì)象會(huì)放入一個(gè)hash表中

用weak指向的對(duì)象內(nèi)存地址作為key九默,當(dāng)此對(duì)象的引用計(jì)數(shù)為0的時(shí)候會(huì)dealloc

假如weak指向的對(duì)象內(nèi)存地址是a震放,那么就會(huì)以a為鍵,在這個(gè)weak表中搜索驼修,找到所有以a為鍵的weak對(duì)象從而設(shè)置為 nil

26殿遂、runtime怎么添加屬性、方法等

????1乙各、class_addIvar墨礁、class_addMethod、class_addProperty耳峦、class_addProtocol恩静、class_replaceProperty

27、_objc_msgForward函數(shù)是做什么的蹲坷?直接調(diào)用它將會(huì)發(fā)生什么

_objc_msgForward是IMP類型蜕企,用于消息轉(zhuǎn)發(fā)的咬荷,當(dāng)向一個(gè)對(duì)象發(fā)送一條消息,但它并沒(méi)有實(shí)現(xiàn)的時(shí)候轻掩,_objc_msgForward會(huì)嘗試做消息轉(zhuǎn)發(fā)

28幸乒、*** 消息傳遞與函數(shù)調(diào)用之間的區(qū)別, OC是怎么調(diào)用函數(shù)的

可以隨時(shí)對(duì)一個(gè)對(duì)象傳遞任何消息唇牧,而不需要在編譯的時(shí)候聲明這些方法

消息傳遞:運(yùn)行時(shí)所執(zhí)行的代碼由運(yùn)行時(shí)環(huán)境決定罕扎,消息傳遞可以隨時(shí)對(duì)一個(gè)對(duì)象傳遞任何消息,并且不需要在編譯的時(shí)候去聲明這些方法

函數(shù)調(diào)用:運(yùn)行時(shí)所執(zhí)行的代碼由編譯器決定 函數(shù)如果沒(méi)有聲明就去調(diào)用的話丐重,會(huì)造成編譯失敗腔召,而消息就不會(huì)這樣

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市扮惦,隨后出現(xiàn)的幾起案子臀蛛,更是在濱河造成了極大的恐慌,老刑警劉巖崖蜜,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浊仆,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡豫领,警方通過(guò)查閱死者的電腦和手機(jī)抡柿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)等恐,“玉大人洲劣,你說(shuō)我怎么就攤上這事】问撸” “怎么了囱稽?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)二跋。 經(jīng)常有香客問(wèn)我粗悯,道長(zhǎng),這世上最難降的妖魔是什么同欠? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任样傍,我火速辦了婚禮,結(jié)果婚禮上铺遂,老公的妹妹穿的比我還像新娘衫哥。我一直安慰自己,他們只是感情好襟锐,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布撤逢。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蚊荣。 梳的紋絲不亂的頭發(fā)上初狰,一...
    開(kāi)封第一講書(shū)人閱讀 52,255評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音互例,去河邊找鬼奢入。 笑死,一個(gè)胖子當(dāng)著我的面吹牛媳叨,可吹牛的內(nèi)容都是我干的腥光。 我是一名探鬼主播,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼糊秆,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼武福!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起痘番,我...
    開(kāi)封第一講書(shū)人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤捉片,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后汞舱,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體伍纫,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年兵拢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逾礁。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡说铃,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出嘹履,到底是詐尸還是另有隱情腻扇,我是刑警寧澤,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布砾嫉,位于F島的核電站幼苛,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏焕刮。R本人自食惡果不足惜舶沿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望配并。 院中可真熱鬧括荡,春花似錦、人聲如沸溉旋。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至邑闲,卻和暖如春算行,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背苫耸。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工州邢, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鲸阔。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓偷霉,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親褐筛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子类少,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359