Runtime詳解

最近在研究Runtime,因此,打算寫一篇文章跟小伙伴兒們分享一下。好了,廢話不多說,直接上干貨。

RunTime簡稱運行時。OC就是運行時機制,也就是在運行時候的一些機制,其中最主要的是消息機制。簡單說一下C與OC在編譯和運行階段的區(qū)別,對于C語言,函數(shù)的調用在編譯的時候會決定調用哪個函數(shù)。對于OC的函數(shù),屬于動態(tài)調用過程,在編譯的時候并不能決定真正調用哪個函數(shù),只有在真正運行的時候才會根據(jù)函數(shù)的名稱找到對應的函數(shù)來調用。

Runtime有5大作用:發(fā)送消息,交換方法,動態(tài)添加方法,給分類添加屬性,字典轉模型,下面一一給大家講解一下這5個作用。


一、發(fā)送消息

任何方法調用的本質就是發(fā)送一個消息,用runtime發(fā)送消息,OC底層就是通過runtime實現(xiàn)的。下面給大家展示一下底層的代碼:

正常的OC代碼通過Xcode的編譯器Clang重新編譯,就會生成底層的代碼,也就是消息機制的代碼。話說回來,怎么使用編譯器重新編譯呢?我們在終端輸入clang -rewrite-objc main.m 就可以得到最終生成代碼了。

我們使用Runtime時,必須要提前導入頭文件<objc/message.h>,可能有人會問我,為什么不導入<objc/runtime.h>?因為我們進入message.h的聲明中,會發(fā)現(xiàn)已經導入了runtime.h。

上面展示的代碼是最底層的代碼,寫著太麻煩了,很少用,下面給大家展示一下我們平常寫的代碼:

這個就是我們平常寫的,第一個參數(shù)的意思是:誰發(fā)送消息?????? 第二個參數(shù)的意思是:發(fā)送什么消息。

其實,還有一種寫法,也是可以的:

上面僅僅給大家展示了一些消息機制底層代碼的一下寫法,下面說一下Runtime在消息機制中最重要的一個作用:“runtime消息機制,可以調用私有方法”?。。。。?!

下面給大家展示一下,調用私有方法:


上面的eat,run方法在Person類中均沒有聲明,只有實現(xiàn)。

注:我們在用對象p調用方法時,不要用Person *p = objc_msgSend(object_getClass(@"Person"), sel_registerName("alloc"))這種形式,否則,會崩。

上面是對象方法,下面給大家展示一下類方法。

對象方法的對象調用,類方法的本質是類對象調用。


下面,給大家分享一下方法的調用流程:

1.去尋找對應的類對象,每一個對象都有一個isa指針,通過isa指針去對應類中查找;

2.注冊方法編號

3.根據(jù)方法編號查找對應的方法

4.找到只是最終函數(shù)實現(xiàn)地址,根據(jù)地址去方法區(qū)調用對應函數(shù)。



二、交換方法

交換方法是Runtime中最常用的,我們在做項目時經常用到。

Runtime(交換方法):只要想修改系統(tǒng)的方法實現(xiàn)。

比如:有一個項目,已經開發(fā)了2年,忽然項目負責人添加一個功能,每次UIImage加載圖片,告訴我是否加載成功?

這樣的一個需求,除了使用Runtime交換方法,用其他的方法很難實現(xiàn)。

交換方法的步驟為:(1)給系統(tǒng)的方法添加分類;

??????????????????????????????? (2)自己實現(xiàn)一個帶有擴展功能的方法;

??????????????????????????????? (3)交換方法的實現(xiàn),只需要交換一次。

下面直接上代碼:

分類的聲明:

分類的實現(xiàn):



三、動態(tài)添加方法

動態(tài)添加方法:OC是懶加載機制,只要一個方法實現(xiàn)了,就會馬上添加到方法列表中(不管這個方法有沒有用過,都會添加進去)。如果某個類中方法比較多,而且有很多方法不常用,需要給每個方法都生成映射表,加載類到內存的時候就比較耗費資源,可以使用動態(tài)給該類添加方法解決。

下面直接上代碼:

Person類的實現(xiàn)部分:

動態(tài)添加方法在做項目時用得比較少。


4、動態(tài)添加屬性

我們給系統(tǒng)的類添加屬性的時候,可以使用runtime動態(tài)添加屬性。動態(tài)添加屬性的本質:讓某個屬性和某個對象產生一個關聯(lián),并不是直接把這個值的內存空間添加到類內存空間。

代碼如下:

給系統(tǒng)的類添加一個分類,聲明部分:


實現(xiàn)部分:




4、字典轉模型

字典轉模型有兩種方法:1.KVC? 2.Runtime。第三方框架MJExtension底層就是用Runtime字典轉模型的。

KVC的實現(xiàn)原理是:遍歷字典中所有的key,去模型中查找對應的屬性賦值;Runtime實現(xiàn)原理剛好與KVC相反:通過runtime,把一個模型中所有屬性遍歷出來,根據(jù)屬性去字典里面找。

我們可以創(chuàng)建一個NSObject分類,專門字典轉模型,以后所有模型都可以通過這個分類轉

代碼如下:


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

相關閱讀更多精彩內容

  • 參考鏈接: http://www.cnblogs.com/ioshe/p/5489086.html 簡介 Runt...
    樂樂的簡書閱讀 2,252評論 0 9
  • 運行時是iOS中一個很重要的概念,iOS運行過程中都會被轉化為runtime的C代碼執(zhí)行。例如[target do...
    蘿卜醬紫閱讀 533評論 0 3
  • 公司項目用到一個三方開源庫,里面有個bug,不能改動源碼,我想來想去,只能通過runtime這個萬能的手段來解決。...
    夜千尋墨閱讀 18,598評論 41 205
  • 對于從事 iOS 開發(fā)人員來說,所有的人都會答出【runtime 是運行時】什么情況下用runtime?大部分人能...
    夢夜繁星閱讀 3,821評論 7 64
  • 車牌號的組成一般為:省份 + 地區(qū)代碼 + 5位數(shù)字/字母。車牌號碼查詢
    謝小帥閱讀 6,027評論 0 0

友情鏈接更多精彩內容