文章分享至個人我的技術博客: https://cainluo.github.io/15077238804616.htmlhtml
講到這裏, RunTime
的知識點和應用基本上就已經講完了, 剩下的就靠你們本身在項目中的應用以及累積了.git
這一篇文章主要是github
轉載聲明:如須要轉載該文章, 請聯繫做者, 而且註明出處, 以及不能擅自修改本文.面試
基礎路徑圖:數組
在學習RunTime
的基礎時, 咱們要搞清楚一些重要的東西, 一些專業術語:微信
咱們能夠從這些東西里獲取到指定類的全部信息, 不管是公開的, 仍是私有的, 所有均可以拿到, 而且操做.函數
PS: 但操做私有方法的時候, 注意不要用來上架, 除非你有方法讓蘋果審覈的時候經過.佈局
進階路徑圖:學習
在學習RunTime
進階的時候, 咱們就要了解更加的深刻.指針
resolveInstanceMethod:
YES
, 經過class_addMethod
消息獲得處理, 結束NO
, 進入forwardingTargetForSelector
selector
, 消息獲得處理, 結束selector
methodSignatureForSelector
, 指定方法簽名, 調用forwardInvovation
, 經過anInvocation
作處理, 消息獲得處理, 結束應用路徑圖:
在學習完RunTime
以後, 咱們就能夠應用到咱們的實際開發中.
在實際開發中, 咱們有一些實例場景會用到RunTime
:
ViewController
的聲明週期UINavigationBar
的backButtonItem
Runtime Method Swizzling開發實例彙總
問題: objc在向一個對象發送消息時, 發生了什麼? |
---|
1.根據對象的isa 指針找到類對象id , 在查詢類對象裏面的methodLists 方法函數列表 |
2.若是沒有在好到, 在沿着superClass , 尋找父類,再在父類methodLists 方法列表裏面查詢 |
3.最終找到SEL , 根據id 和SEL 確認IMP (指針函數), 在發送消息. |
問題: 何時會報unrecognized selector 錯誤? iOS 有哪些機制來避免走到這一步? |
---|
1.當發送消息的時候, 咱們會根據類裏面的methodLists 列表去查詢咱們要動用的SEL , 當查詢不到的時候, 咱們會一直沿着父類查詢 |
2.當最終查詢不到的時候咱們會報unrecognized selector 錯誤, 當系統查詢不到方法的時候, 會調用+(BOOL)resolveInstanceMethod:(SEL)sel 動態解釋的方法來給我一次機會來添加, 調用不到的方法. |
3.或者咱們能夠再次使用-(id)forwardingTargetForSelector:(SEL)aSelector 重定向的方法來告訴系統,該調用什麼方法,一來保證不會崩潰. |
問題: 可否向編譯後獲得的類中增長實例變量?可否向運行時建立的類中添加實例變量? 爲何? |
---|
1.不能向編譯後獲得的類增長實例變量. |
2.能向運行時建立的類中添加實例變量. |
解釋: |
1. 編譯後的類已經註冊在runtime 中,類結構體中的objc_ivar_list 實例變量的鏈表和instance_size 實例變量的內存大小已經肯定,runtime 會調用class_setvarlayout 或class_setWeaklvarLayout 來處理strong``weak 引用.因此不能向存在的類中添加實例變量. |
2. 運行時建立的類是能夠添加實例變量,調用class_addIvar 函數. 可是的在調用objc_allocateClassPair 以後,objc_registerClassPair 以前,緣由同上. |
問題: runtime如何實現weak變量的自動置nil? |
---|
1.runtime 對註冊的類, 會進行佈局,對於weak 對象會放入一個hash 表中。 用weak 指向的對象內存地址做爲key ,當此對象的引用計數爲0 的時候會dealloc . |
2.假如weak 指向的對象內存地址是A ,那麼就會以A 爲鍵, 在這個weak 表中搜索,找到全部以A 爲鍵的weak 對象,從而設置爲nil . |
問題: 給類添加一個屬性後,在類結構體裏哪些元素會發生變化 |
---|
1.instance_size :實例的內存大小. |
2.objc_ivar_list *ivars : 屬性列表. |
好了, 終於到尾聲了, 但願你們能夠在個人文章裏學到知識, 早日迎娶白富美, 走上人生巔峯, 最後附上全部的文章: