玩轉(zhuǎn)iOS開發(fā):裝逼技術(shù)RunTime的總結(jié)篇

推薦閱讀:iOS開發(fā)——BAT面試題合集(持續(xù)更新中)

基礎(chǔ)路徑圖:

image

<figcaption style="display: block; margin: auto; text-align: center;">1</figcaption>

在學(xué)習(xí) RunTime 的基礎(chǔ)時(shí), 我們要搞清楚一些重要的東西, 一些專業(yè)術(shù)語:

  • SEL
  • id
  • Class
  • Method
  • Ivar
  • IMP
  • Cache
  • Property

我們可以從這些東西里獲取到指定類的所有信息, 無論是公開的, 還是私有的, 全部都可以拿到, 并且操作.

PS: 但操作私有方法的時(shí)候, 注意不要用來上架, 除非你有方法讓蘋果審核的時(shí)候通過.

RunTime進(jìn)階

進(jìn)階路徑圖:

image

<figcaption style="display: block; margin: auto; text-align: center;">2</figcaption>

在學(xué)習(xí) RunTime 進(jìn)階的時(shí)候, 我們就要了解更加的深入.

消息機(jī)制:

  • objc_msgSend
  • objc_msgSend_fpret
  • objc_msgSend_stret
  • objc_msgSendSuper
  • objc_msgSendSuper_stret

對象關(guān)聯(lián):

  • objc_setAssociatedObject()
  • objc_getAssociatedObject()
  • objc_removeAssociatedObjects()

對象關(guān)聯(lián)的策略:

  • OBJC_ASSOCIATION_ASSIGN
  • OBJC_ASSOCIATION_RETAIN_NONATOMIC
  • OBJC_ASSOCIATION_COPY_NONATOMIC
  • OBJC_ASSOCIATION_RETAIN
  • OBJC_ASSOCIATION_COPY

動態(tài)方法解析:

  • resolveInstanceMethod:
    • YES , 通過 class_addMethod 消息得到處理, 結(jié)束
    • NO , 進(jìn)入 forwardingTargetForSelector
      • 指定響應(yīng) selector , 消息得到處理, 結(jié)束
      • 不指定響應(yīng) selector
        • 進(jìn)入 methodSignatureForSelector , 指定方法簽名, 調(diào)用 forwardInvovation , 通過 anInvocation 做處理, 消息得到處理, 結(jié)束
        • 不指定方法簽名, 該消息沒有得到處理, 系統(tǒng)報(bào)錯

RunTime應(yīng)用

應(yīng)用路徑圖:

image

<figcaption style="display: block; margin: auto; text-align: center;">3</figcaption>

在學(xué)習(xí)完 RunTime 之后, 我們就可以應(yīng)用到我們的實(shí)際開發(fā)中.

Category

  • 關(guān)聯(lián)對象
  • 控制對象

Class

  • 動態(tài)添加方法
  • 動態(tài)交換方法
  • 動態(tài)攔截并替換方法
  • 動態(tài)給方法添加額外功能

Model

  • 自動歸檔和解檔
  • 自動字典轉(zhuǎn)模型
    • 字典轉(zhuǎn)模型(模型屬性數(shù)量大于字典key數(shù)量)
    • 字典轉(zhuǎn)模型(模型中嵌套模型)
    • 字典轉(zhuǎn)模型(數(shù)組中嵌套模型)

RunTime實(shí)例開發(fā)場景

在實(shí)際開發(fā)中, 我們有一些實(shí)例場景會用到 RunTime :

  • 替換 ViewController 的聲明周期
  • 解決集合類因索引的問題崩潰的問題
  • 防止按鈕重復(fù)高強(qiáng)度點(diǎn)擊
  • 全局更換控件初始效果
  • App熱修復(fù)
  • App異常加載的展位圖
  • 全局修改 UINavigationBarbackButtonItem

Runtime Method Swizzling開發(fā)實(shí)例匯總

RunTime面試題及答案

問題: objc在向一個(gè)對象發(fā)送消息時(shí), 發(fā)生了什么?
1.根據(jù)對象的 isa 指針找到類對象 id , 在查詢類對象里面的 methodLists 方法函數(shù)列表
2.如果沒有在好到, 在沿著 superClass , 尋找父類,再在父類 methodLists 方法列表里面查詢
3.最終找到 SEL , 根據(jù) idSEL 確認(rèn) IMP (指針函數(shù)), 在發(fā)送消息.
問題: 什么時(shí)候會報(bào) unrecognized selector 錯誤? iOS 有哪些機(jī)制來避免走到這一步?
1.當(dāng)發(fā)送消息的時(shí)候, 我們會根據(jù)類里面的 methodLists 列表去查詢我們要動用的 SEL , 當(dāng)查詢不到的時(shí)候, 我們會一直沿著父類查詢
2.當(dāng)最終查詢不到的時(shí)候我們會報(bào) unrecognized selector 錯誤, 當(dāng)系統(tǒng)查詢不到方法的時(shí)候, 會調(diào)用 +(BOOL)resolveInstanceMethod:(SEL)sel 動態(tài)解釋的方法來給我一次機(jī)會來添加, 調(diào)用不到的方法.
3.或者我們可以再次使用 -(id)forwardingTargetForSelector:(SEL)aSelector 重定向的方法來告訴系統(tǒng),該調(diào)用什么方法,一來保證不會崩潰.
問題: 能否向編譯后得到的類中增加實(shí)例變量?能否向運(yùn)行時(shí)創(chuàng)建的類中添加實(shí)例變量? 為什么?
1.不能向編譯后得到的類增加實(shí)例變量.
2.能向運(yùn)行時(shí)創(chuàng)建的類中添加實(shí)例變量.
解釋:
1. 編譯后的類已經(jīng)注冊在 runtime 中,類結(jié)構(gòu)體中的 objc_ivar_list 實(shí)例變量的鏈表和 instance_size 實(shí)例變量的內(nèi)存大小已經(jīng)確定, runtime 會調(diào)用 class_setvarlayoutclass_setWeaklvarLayout 來處理 strong``weak 引用.所以不能向存在的類中添加實(shí)例變量.
2. 運(yùn)行時(shí)創(chuàng)建的類是可以添加實(shí)例變量,調(diào)用 class_addIvar 函數(shù). 但是的在調(diào)用 objc_allocateClassPair 之后, objc_registerClassPair 之前,原因同上.
問題: runtime如何實(shí)現(xiàn)weak變量的自動置nil?
1. runtime 對注冊的類, 會進(jìn)行布局,對于 weak 對象會放入一個(gè) hash 表中。 用 weak 指向的對象內(nèi)存地址作為 key ,當(dāng)此對象的引用計(jì)數(shù)為 0 的時(shí)候會 dealloc .
2.假如 weak 指向的對象內(nèi)存地址是 A ,那么就會以 A 為鍵, 在這個(gè) weak 表中搜索,找到所有以 A為鍵的 weak 對象,從而設(shè)置為 nil .
問題: 給類添加一個(gè)屬性后,在類結(jié)構(gòu)體里哪些元素會發(fā)生變化
1. instance_size :實(shí)例的內(nèi)存大小.
2. objc_ivar_list *ivars : 屬性列表.

總結(jié)

好了, 終于到尾聲了, 希望大家可以在我的文章里學(xué)到知識, 早日迎娶白富美, 走上人生巔峰, 最后附上所有的文章:

RunTime快速入門

文章來源于網(wǎng)絡(luò),如有侵權(quán)請聯(lián)系小編刪除

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容