哈哈好久沒有寫簡書了,最近在看各個模塊的面試題,今天總結(jié)下runtime的面試題蒲稳。
1氮趋、什么是runtime伍派?
- runtime是運(yùn)行時,是一套比較底層的C語言API。
- 平時編寫的OC代碼剩胁,需要runtime來創(chuàng)建類和對象诉植,進(jìn)行消息發(fā)送和轉(zhuǎn)發(fā),其實最終會轉(zhuǎn)換成Runtime的C語言代碼昵观。
- runtime是將數(shù)據(jù)類型的確定由編譯時推遲到了運(yùn)行時晾腔。
2舌稀、為什么需要 runtime?
- OC是一門動態(tài)語言灼擂,它會將一些工作放在代碼的運(yùn)行時才去處理而并非編譯時壁查,因此編譯器是不夠,我們還需要一個運(yùn)行時系統(tǒng)來處理編譯后的代碼剔应。
- (拓展)runtime基本是用C語言和匯編語言寫的睡腿,蘋果和GNU各自維護(hù)一個開源的runtime版本,這兩個版本之間都高度的保持一致峻贮。
3席怪、runtime 有什么作用?
- 消息傳遞纤控、轉(zhuǎn)發(fā)<消息機(jī)制>
- 訪問私有變量 --eg:(UITextFiled 的修改)
- 交換系統(tǒng)方法 --eg:(攔截--防止button連續(xù)點擊)
- 動態(tài)增加方法 --(然并卵 求大神指點)
- 為分類增加屬性 --(用的比較多)
- 字典轉(zhuǎn)模型 -- eg:(YYModel框架可以去看看源碼)
4挂捻、簡單的分析消息機(jī)制的原理以及過程
- 消息機(jī)制的原理:對象根據(jù)方法編號SEL去映射表查找對應(yīng)的方法實現(xiàn)
- 簡單過程: 首先通過方法編號SEL 去類實現(xiàn)的list表中查找 實現(xiàn)的IMP 直到找到為止 ---> 如果找不到, 就會開始進(jìn)入動態(tài)法法解析
5、runtime如何通過selector找到對應(yīng)的IMP地址船万?(分別考慮類方法和實例方法)刻撒?
- 每個類對象中都有一個對象的方法列表(IMP) -- <對象方法緩存>。
- 實例方法列表存放在該對象的isa指針指向的類唬涧。
- 類方法列表是存放在類對象中isa指針指向的元類對象中 -- <類方法緩存>疫赎。
- 方法列表中每一個方法的結(jié)構(gòu)體中記錄著方法的名稱,方法的實現(xiàn)碎节,參數(shù)類型捧搞。
- selector 的本質(zhì)就是方法名稱,通過方法名稱就可以在方法列表中找到對應(yīng)的方法實現(xiàn)狮荔。
- 當(dāng)我們發(fā)送一個消息給NSObject對象的時候胎撇,這個消息就在對象的類對象方法列表中查找。
- 當(dāng)我們發(fā)送一個消息給一個類時殖氏,這條消息會在類的Meta Class對象的方法列表里查找晚树。
- (拓展)元類,就像之前的類一樣雅采,它也是一個對象爵憎,所有的元類都使用根元類(繼承體系中處于頂端的類的元類)作為他們的類。這就意味著所有NSObject的子類(大多數(shù)類)的元類都會以NSObject的元類作為他們的類婚瓜,根據(jù)這個規(guī)則宝鼓,所有的元類使用根元類作為他們的類,根元類的元類則就是它自己巴刻。也就是說基類的元類的isa指針指向他自己愚铡。
6、runtime怎么添加屬性、方法等
- runtime 的函數(shù)方法中有相關(guān)的增加函數(shù)
- class_addIvar (ivar 成員變量)
- class_addMethod
- class_addProperty
- class_addProtocol
- 等沥寥。碍舍。。
7邑雅、_objc_msgForward函數(shù)是做什么的片橡?直接調(diào)用它將會發(fā)生什么?
- _objc_msgForward是IMP類型淮野,用于消息轉(zhuǎn)發(fā)的:當(dāng)向一個對象發(fā)送一條消息锻全,但它并沒有實現(xiàn)的時候,_objc_msgForward會嘗試做消息轉(zhuǎn)發(fā)
- (拓展)直接調(diào)用_objc_msgForward是非常危險 《[JSPatch]就是直接調(diào)用_objc_msgForward來實現(xiàn)其核心功能的》
8录煤、簡述下Objective-C中調(diào)用方法的過程(runtime)鳄厌?
- Objective-C是動態(tài)語言,每個方法在運(yùn)行時會被動態(tài)轉(zhuǎn)為消息發(fā)送
- objc在向一個對象發(fā)送消息時妈踊,runtime庫會根據(jù)對象的isa指針找到該對象實際所屬的類
- 然后在該類中的方法列表以及其父類方法列表中尋找方法運(yùn)行
- 如果了嚎,在最頂層的父類(一般也就NSObject)中依然找不到相應(yīng)的方法時,程序在運(yùn)行時會掛掉并拋出異常unrecognized selector sent to XXX
- 但是在這之前廊营,objc的運(yùn)行時會給出三次拯救程序崩潰的機(jī)會歪泳,這三次拯救程序奔潰的說明見問題《什么時候會報unrecognized selector的異常》中的說明
- 補(bǔ)充說明:Runtime 鑄就了Objective-C 是動態(tài)語言的特性露筒,使得C語言具備了面向?qū)ο蟮奶匦阅派。诔绦蜻\(yùn)行期創(chuàng)建,檢查慎式,修改類伶氢、對象及其對應(yīng)的方法,這些操作都可以使用runtime中的對應(yīng)方法實現(xiàn)瘪吏。
如有問題多多指點
后續(xù)增加