玩轉iOS開發:裝逼技術RunTime的總結篇

文章分享至個人我的技術博客: https://cainluo.github.io/15077238804616.htmlhtml


講到這裏, RunTime的知識點和應用基本上就已經講完了, 剩下的就靠你們本身在項目中的應用以及累積了.git

這一篇文章主要是github

轉載聲明:如須要轉載該文章, 請聯繫做者, 而且註明出處, 以及不能擅自修改本文.面試


RunTime基礎

基礎路徑圖:數組

1

在學習RunTime的基礎時, 咱們要搞清楚一些重要的東西, 一些專業術語:微信

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

咱們能夠從這些東西里獲取到指定類的全部信息, 不管是公開的, 仍是私有的, 所有均可以拿到, 而且操做.函數

PS: 但操做私有方法的時候, 注意不要用來上架, 除非你有方法讓蘋果審覈的時候經過.佈局


RunTime進階

進階路徑圖:學習

2

在學習RunTime進階的時候, 咱們就要了解更加的深刻.指針

消息機制:

  • objc_msgSend
  • objc_msgSend_fpret
  • objc_msgSend_stret
  • objc_msgSendSuper
  • objc_msgSendSuper_stret

對象關聯:

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

對象關聯的策略:

  • OBJC_ASSOCIATION_ASSIGN
  • OBJC_ASSOCIATION_RETAIN_NONATOMIC
  • OBJC_ASSOCIATION_COPY_NONATOMIC
  • OBJC_ASSOCIATION_RETAIN
  • OBJC_ASSOCIATION_COPY

動態方法解析:

  • resolveInstanceMethod:
    • YES, 經過class_addMethod消息獲得處理, 結束
    • NO, 進入forwardingTargetForSelector
      • 指定響應selector, 消息獲得處理, 結束
      • 不指定響應selector
        • 進入methodSignatureForSelector, 指定方法簽名, 調用forwardInvovation, 經過anInvocation作處理, 消息獲得處理, 結束
        • 不指定方法簽名, 該消息沒有獲得處理, 系統報錯

RunTime應用

應用路徑圖:

3

在學習完RunTime以後, 咱們就能夠應用到咱們的實際開發中.

Category

  • 關聯對象
  • 控制對象

Class

  • 動態添加方法
  • 動態交換方法
  • 動態攔截並替換方法
  • 動態給方法添加額外功能

Model

  • 自動歸檔和解檔
  • 自動字典轉模型
    • 字典轉模型(模型屬性數量大於字典key數量)
    • 字典轉模型(模型中嵌套模型)
    • 字典轉模型(數組中嵌套模型)

RunTime實例開發場景

在實際開發中, 咱們有一些實例場景會用到RunTime:

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

Runtime Method Swizzling開發實例彙總


RunTime面試題及答案

問題: objc在向一個對象發送消息時, 發生了什麼?
1.根據對象的isa指針找到類對象id, 在查詢類對象裏面的methodLists方法函數列表
2.若是沒有在好到, 在沿着superClass, 尋找父類,再在父類methodLists方法列表裏面查詢
3.最終找到SEL, 根據idSEL確認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_setvarlayoutclass_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 : 屬性列表.

總結

好了, 終於到尾聲了, 但願你們能夠在個人文章裏學到知識, 早日迎娶白富美, 走上人生巔峯, 最後附上全部的文章:

RunTime快速入門

RunTime應用


最後

碼字很費腦, 看官賞點飯錢可好

微信

支付寶
相關文章
相關標籤/搜索