Runtime在平時項(xiàng)目使用案例(干貨篇)

我們在面試中經(jīng)常會被問到這些問題,到底怎么回答比較合適?


這樣我們先去看一下我們平時項(xiàng)目中用到的Runtime,等下我們再來概括上面的問題的答案.我們肯定是用Runtime提供的API去做一些事情.

我們肯定是多多少少有接觸Runtime,如果面試官問你,你肯定回答用過,不然說明你對Runtime一點(diǎn)都不了解.這樣對你的印象就大打折扣了.

現(xiàn)在我就列一些我們可能用到的API(注意只是部分,不是所有).

作為一個開發(fā)者,有一個學(xué)習(xí)的氛圍跟一個交流圈子特別重要,這是一個我的iOS開發(fā)交流群:130 595 548,不管你是小白還是大牛都?xì)g迎入駐 ,讓我們一起進(jìn)步,共同發(fā)展?。ㄈ簝?nèi)會免費(fèi)提供一些群主收藏的免費(fèi)學(xué)習(xí)書籍資料以及整理好的幾百道面試題和答案文檔?。?/p>

Runtime類相關(guān)的API

Runtime成員變量相關(guān)的API

Runtime屬性相關(guān)的API

Runtime方法相關(guān)的API

上面就是我們可能會遇到的一些的API,而且有些我們是用過的,比如獲取對象的內(nèi)存大小、替換方法、關(guān)聯(lián)對象、添加方法等等.接下來我們就去看部分案例用法:(只列舉部分用法,因?yàn)楸容^多)其他要用的時候,我們可以自己查閱.

先看相關(guān)的應(yīng)用:

1.object_getClass:獲取isa指向的class對象

2.object_setClass:設(shè)置isa指向的class

3.object_isClass:判斷一個OC對象是否為Class

4.objc_allocateClassPair:動態(tài)創(chuàng)建一個類(參數(shù):父類,類名,額外的內(nèi)存空間)

在不用這個類的時候釋放它: objc_disposeClassPair(NewClass).

當(dāng)然這個也可以給現(xiàn)有的類增加屬性.大家可以自己嘗試

5.class_copyIvarList:獲取類的屬性,這個在開發(fā)中遇到的較多,很多框架的數(shù)據(jù)解析等等都是用了這個,(注意:runtime中copy或者create等創(chuàng)建出來的都需要free).

項(xiàng)目實(shí)戰(zhàn)應(yīng)用實(shí)例

1.修改UITextField提示的顏色

首先我們看下我們用自帶的是如何實(shí)現(xiàn)的

我們可以用NSMutableAttributedString去修改UITextField的提示顏色.,因?yàn)橐獙懙拇a比較多,如果我們不用這個,那我們可以考慮用runtime去實(shí)現(xiàn)?首先我們想紅色的內(nèi)容極有可能是UILabel,我們就窺探UITextField里面有哪些屬性,請看下圖:

然后用kvc去賦值就行了,這樣就很簡單了(注意賦值之前要先設(shè)置一個placehold,因?yàn)檫@個label是懶加載創(chuàng)建的).通過這種思路我們就可以去遍歷系統(tǒng)的某些成員變量了,可以做更多便捷的事.

2.說一下開發(fā)中的字典轉(zhuǎn)模型的應(yīng)用

傳統(tǒng)的我就不演示了,直接演示runtime的操作,我們NSObject創(chuàng)建一個分類,這樣模型都能直接調(diào)用,請看下圖代碼:先看下結(jié)果,這樣的話,有n多個要解析,都是可以做到(注意我這邊只是寫了一點(diǎn)點(diǎn)代碼,具體用還有很多注意事項(xiàng),這里只是一個思路).

就這樣簡短的代碼就能解決問題,再來一個類照樣可以調(diào)用這樣的方法.有些字典轉(zhuǎn)模型的框架就是里面用了這些操作,當(dāng)然成熟的框架肯定考慮了很多情況,比如出現(xiàn)繼承,出現(xiàn)nil等等的處理,我們只是寫了一個簡短的代碼演示.

最后再介紹一下方法相關(guān)的.

1.class_replaceMethod:方法替換

2.imp_implementationWithBlock:也可用block作為方法實(shí)現(xiàn)

3.重點(diǎn):方法交換

其實(shí)方法交換的用處非常大,比如我看到一些視頻公開課,說什么,永久解決數(shù)組越界的問題!這里面也是用到runtime的方法交互,再比如我想統(tǒng)計所有按鈕的點(diǎn)擊次數(shù),如果不用runtime去實(shí)現(xiàn),就比較麻煩,而用runtime就非常的簡單,最多的用處我們還是去替換系統(tǒng)的方法!

下面就舉一個攔截所有按鈕點(diǎn)擊事件的例子

我們知道UIButton是繼承UIControl,所以我們創(chuàng)建一個分類.

首先創(chuàng)建一個UIControl的分類,置換代碼如下:

從上面的代碼我們可以看出我們確實(shí)是做到了這個需求,但是你發(fā)現(xiàn)沒,以前的方法就沒有執(zhí)行了,點(diǎn)擊事情的結(jié)果是沒有了,所以我們肯定不想破壞之前的系統(tǒng)的結(jié)構(gòu),所以我們要調(diào)用一下系統(tǒng)的,注意這時候方法已經(jīng)置換,如果調(diào)用請注意.

請看下面的代碼:

這就在不破壞系統(tǒng)的結(jié)構(gòu)下,達(dá)到了我們想要的完美效果.它實(shí)際上是交換IMP的地址值.這里load我們可以里面加一個GCD函數(shù)的dispatch_once函數(shù),因?yàn)槲覀儾荒鼙WCload函數(shù)只執(zhí)行一次,我們只需要置換一次,再置換就換回來了,用dispatch_once保證只執(zhí)行一次.

我們看一下源碼(源碼地址之前的博客都有提到,現(xiàn)在我用的是818版本)

源碼查看

我們從源碼也能看出來,是直接交換imp地址.是rw_t里面的method集合里面的方法的imp直接置換的.flushCaches是清除緩存,可以點(diǎn)進(jìn)去看具體實(shí)現(xiàn).這個把系統(tǒng)的方法替換掉,也就是我們常說的hook,鉤子函數(shù)!

基本要說的就這么多,還有很多其他的用法,我們可以自己嘗試.

總結(jié)

1.什么是Runtime?

OC是一門動態(tài)性比較強(qiáng)的編程語言,允許很多操作推遲到程序運(yùn)行時再進(jìn)行,

OC的動態(tài)性就是由Runtime來支撐和實(shí)現(xiàn)的,Runtime是一套C語言的API,封裝了很多動態(tài)性相關(guān)的函數(shù)

平時編寫的OC代碼,底層都是轉(zhuǎn)換了Runtime API進(jìn)行調(diào)用

2平時項(xiàng)目有用到過嗎?

利用關(guān)聯(lián)對象(AssociatedObject)給分類添加屬性;

遍歷類的所有成員變量(修改textfield的占位文字顏色、字典轉(zhuǎn)模型、自動歸檔解檔);

交換方法實(shí)現(xiàn)(交互系統(tǒng)的方法);

利用消息轉(zhuǎn)發(fā)機(jī)制解決方法找不到的異常的問題;

等等等,所有一切你用到的都可以寫上去.

...

如果覺得我寫得對您有所幫助,請關(guān)注我,我會持續(xù)更新??

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

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

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