Runtime 10種用法(沒(méi)有比這更全的了)

閱讀了多篇運(yùn)行時(shí)的文章,感覺(jué)都很不錯(cuò),從幾篇文章里面提取一些個(gè)人認(rèn)為比較重要的,偏實(shí)戰(zhàn)的知識(shí)點(diǎn)的摘錄,另外還結(jié)合了個(gè)人的創(chuàng)造形成此文。再牛逼的技術(shù)和實(shí)戰(zhàn)結(jié)合才有意義,本篇介紹技術(shù)盡量和實(shí)戰(zhàn)聯(lián)系起來(lái),有些沒(méi)講明白的,我給的鏈接里面都有,所以我就不贅述了,如果覺(jué)得可以就點(diǎn)個(gè)贊吧,哈哈。不需要打賞。

1)替換系統(tǒng)方法,

2)字典轉(zhuǎn)model,

3)歸檔,

4)萬(wàn)能控制器跳轉(zhuǎn)

四個(gè)偏實(shí)戰(zhàn)的方法從不同的文章中聚合到這里.沒(méi)講明白的麻煩看客去我給的鏈接里面看看,他們都講了


對(duì)文章的內(nèi)容我用一張圖介紹吧(圖只管明了,我喜歡,大家也喜歡)

#??appstore審核問(wèn)答群:369250107,建了個(gè)倉(cāng)庫(kù):,github[專門解決蘋果拒絕各種問(wèn)題匯總的倉(cāng)庫(kù)](https://github.com/wg689/Solve-App-Store-Review-Problem)

runtime 文章收集:


runtime 文章專題 ? (13+關(guān)于runtime的)


如下4篇內(nèi)容有相似的 小白都可以看懂runtime,值得細(xì)看

文① ?OC最實(shí)用的runtime總結(jié),面試、工作你看我就足夠了!

文②?讓你快速上手Runtime

文③ ?runtime詳解

文④?詳解runtime運(yùn)行時(shí)機(jī)制

文⑤?萬(wàn)能控制器跳轉(zhuǎn)


先用一張圖對(duì)文章做一個(gè)介紹吧 (圖只管,易懂方便回憶,我喜歡,大家也喜歡)?

what(runtime 是什么)

Runtime基本是用C和匯編寫的,可見(jiàn)蘋果為了動(dòng)態(tài)系統(tǒng)的高效而作出的努力。你可以在這里下到蘋果維護(hù)的開(kāi)源代碼。蘋果和GNU各自維護(hù)一個(gè)開(kāi)源的runtime版本,這兩個(gè)版本之間都在努力的保持一致。Objective-C 從三種不同的層級(jí)上與 Runtime 系統(tǒng)進(jìn)行交互,分別是通過(guò) Objective-C 源代碼,通過(guò) Foundation 框架的NSObject類定義的方法通過(guò)對(duì) runtime 函數(shù)的直接調(diào)用。大部分情況下你就只管寫你的Objc代碼就行,runtime 系統(tǒng)自動(dòng)在幕后辛勤勞作著。

RunTime簡(jiǎn)稱運(yùn)行時(shí),就是系統(tǒng)在運(yùn)行的時(shí)候的一些機(jī)制,其中最主要的是消息機(jī)制。

對(duì)于C語(yǔ)言,函數(shù)的調(diào)用在編譯的時(shí)候會(huì)決定調(diào)用哪個(gè)函數(shù),編譯完成之后直接順序執(zhí)行,無(wú)任何二義性。

OC的函數(shù)調(diào)用成為消息發(fā)送。屬于動(dòng)態(tài)調(diào)用過(guò)程。在編譯的時(shí)候并不能決定真正調(diào)用哪個(gè)函數(shù)(事實(shí)證明,在編 譯階段,OC可以調(diào)用任何函數(shù),即使這個(gè)函數(shù)并未實(shí)現(xiàn),只要申明過(guò)就不會(huì)報(bào)錯(cuò)。而C語(yǔ)言在編譯階段就會(huì)報(bào)錯(cuò))

只有在真正運(yùn)行的時(shí)候才會(huì)根據(jù)函數(shù)的名稱找 到對(duì)應(yīng)的函數(shù)來(lái)調(diào)用。

where(哪些地方使用runtime)

1.將某些OC代碼轉(zhuǎn)為運(yùn)行時(shí)代碼,探究底層,比如block的實(shí)現(xiàn)原理(上邊已講到);

2.攔截系統(tǒng)自帶的方法調(diào)用(Swizzle 黑魔法),也可以說(shuō)成對(duì)系統(tǒng)的方法進(jìn)行替換,比如攔截imageNamed:、viewDidLoad、alloc;文/滕先洪(簡(jiǎn)書(shū)作者) ?原文鏈接:http://www.lxweimin.com/p/ab966e8a82e2

需求:比如iOS6 升級(jí) iOS7 后需要版本適配,根據(jù)不同系統(tǒng)使用不同樣式圖片(擬物化和扁平化),如何通過(guò)不去手動(dòng)一個(gè)個(gè)修改每個(gè)UIImage的imageNamed:方法就可以實(shí)現(xiàn)為該方法中加入版本判斷語(yǔ)句?

步驟:

a、為UIImage建一個(gè)分類(UIImage+Category)

b、在分類中實(shí)現(xiàn)一個(gè)自定義方法,方法中寫要在系統(tǒng)方法中加入的語(yǔ)句,比如版本判斷[參考 ]

+ (UIImage*)xh_imageNamed:(NSString*)name {

doubleversion = [[UIDevicecurrentDevice].systemVersiondoubleValue];

if(version >=7.0) {

// 如果系統(tǒng)版本是7.0以上,使用另外一套文件名結(jié)尾是‘_os7’的扁平化圖片

name = [name stringByAppendingString:@"_os7"]; ? ?}

return[UIImagexh_imageNamed:name];

}

c、分類中重寫UIImage的load方法,實(shí)現(xiàn)方法的交換(只要能讓其執(zhí)行一次方法交換語(yǔ)句,load再合適不過(guò)了)

+ (void)load {

// 獲取兩個(gè)類的類方法

Method ?m1 = class_getClassMethod([UIImageclass],@selector(imageNamed:)); ?

Method m2 = class_getClassMethod([UIImageclass],@selector(xh_imageNamed:));

// 開(kāi)始交換方法實(shí)現(xiàn)

method_exchangeImplementations(m1, m2);

}

注意:自定義方法中最后一定要再調(diào)用一下系統(tǒng)的方法,讓其有加載圖片的功能,但是由于方法交換,系統(tǒng)的方法名已經(jīng)變成了我們自定義的方法名(有點(diǎn)繞,就是用我們的名字能調(diào)用系統(tǒng)的方法,用系統(tǒng)的名字能調(diào)用我們的方法),這就實(shí)現(xiàn)了系統(tǒng)方法的攔截!

利用以上思路,我們還可以給 NSObject 添加分類,統(tǒng)計(jì)創(chuàng)建了多少個(gè)對(duì)象,給控制器添加分類,統(tǒng)計(jì)有創(chuàng)建了多少個(gè)控制器,特別是公司需求總變的時(shí)候,在一些原有控件或模塊上添加一個(gè)功能,建議使用該方法!

3.實(shí)現(xiàn)分類也可以增加屬性;

4.實(shí)現(xiàn)NSCoding的自動(dòng)歸檔和自動(dòng)解檔;(不用對(duì)每個(gè)屬性edcode和decode了,如果幾十個(gè)屬性一個(gè)個(gè)的encode和decode真的很麻煩啊,使用運(yùn)行時(shí)可以遍歷出每個(gè)對(duì)象的屬性,數(shù)組的方式遍歷eccode,decode)

用運(yùn)行時(shí)的歸檔方法

不用運(yùn)行時(shí)的歸檔方法:(還好只有5個(gè)屬性,如果20個(gè),30個(gè)或者后臺(tái)突然增加了屬性,這么直接寫死估計(jì)代碼就不靈了)

5.實(shí)現(xiàn)字典和模型的自動(dòng)轉(zhuǎn)換(核心就是可以遍歷出字典中的每個(gè)屬性,json解析中大牛框架都用了這個(gè)特性,包括MJEXtension,YYModel,jsonModel都是將json轉(zhuǎn)換為字典,再遍歷字典中的每個(gè)屬性來(lái)進(jìn)行modle的轉(zhuǎn)換)。


MJextension 使用運(yùn)行時(shí)轉(zhuǎn)換的json轉(zhuǎn)model的部分代碼摘錄

YYModel ?json轉(zhuǎn)model 核心代碼 摘錄


JsonModel json字典轉(zhuǎn)model 摘錄


獲取屬性的列表的方法是字典轉(zhuǎn)模型的比較核心的方法,

OBJC_EXPORT Ivar *class_copyIvarList(Class cls, unsigned int *outCount)

__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);

致此可以下個(gè)結(jié)論嗎?

基本上主流的json 轉(zhuǎn)model 都少不了,使用運(yùn)行時(shí)動(dòng)態(tài)獲取屬性的屬性名的方法,來(lái)進(jìn)行字典轉(zhuǎn)模型替換,字典轉(zhuǎn)模型效率最高的(耗時(shí)最短的)的是KVC,其他的字典轉(zhuǎn)模型是在KVC 的key 和Value 做處理,動(dòng)態(tài)的獲取json 中的key 和value ,當(dāng)然轉(zhuǎn)換的過(guò)程中,第三方框架需要做一些判空啊,鑲嵌的邏輯處理, 再進(jìn)行KVC 轉(zhuǎn)模型.這句代碼 [xx ?setValue:value forKey:key];無(wú)論JsonModle,YYKIt,MJextension 都少不了[xx ?setValue:value forKey:key];這句代碼的,不信可以去搜,這是字典轉(zhuǎn)模型的核心方法,


6)動(dòng)態(tài)增加方法 ?(動(dòng)態(tài)的為某個(gè)類或?qū)ο笤黾右粋€(gè)方法,摘錄文章中有詳細(xì)介紹)


7)動(dòng)態(tài)變量控制 ?(動(dòng)態(tài)對(duì)某個(gè)對(duì)象的變量的值進(jìn)行替換,摘錄文章有詳細(xì)介紹)

8)實(shí)現(xiàn)萬(wàn)能控制器跳轉(zhuǎn)

產(chǎn)品來(lái)一變態(tài)需求,推送過(guò)來(lái)的消息,要跳轉(zhuǎn)到任意控制器.利用runtime動(dòng)態(tài)生成對(duì)象、屬性、方法這特性,我們可以先跟服務(wù)端商量好,定義跳轉(zhuǎn)規(guī)則,比如要跳轉(zhuǎn)到A控制器,需要傳屬性id、type,那么服務(wù)端返回字典給我,里面有控制器名,兩個(gè)屬性名跟屬性值,客戶端就可以根據(jù)控制器名生成對(duì)象,再用kvc給對(duì)象賦值,這樣就搞定了

9)插件開(kāi)發(fā)


插件入門

XCode 有個(gè)很坑爹的地方,就是它并不官方支持插件開(kāi)發(fā),官方?jīng)]有文檔,XCode 也沒(méi)有開(kāi)源,但由于 XCode 是 Objective-C 寫的,OC 動(dòng)態(tài)性太強(qiáng)大,導(dǎo)致在這么封閉的情況下民間還是可以做出各種插件,其核心開(kāi)發(fā)方式就是:

dump 出 Xcode 所有頭文件,知道 Xcode 里有哪些類和接口。

通過(guò)頭文件方法名猜測(cè)方法的作用,swizzle 這些方法,插入自己的代碼實(shí)現(xiàn)插件邏輯。

通過(guò) NSNotificationCenter 監(jiān)聽(tīng)各種事件的發(fā)生。

更詳細(xì)的開(kāi)發(fā)教程網(wǎng)上有不少文章,有興趣的自行搜索吧。

10)Jspath 熱更新 也是使用運(yùn)行時(shí),jspatch 基本上算是黑科技,在線修復(fù)版本bug,微信都使用了這個(gè)技術(shù),詳情百度“JSPatch”,此處省略30000字



______

- 作者開(kāi)發(fā)經(jīng)驗(yàn)總結(jié)的文章推薦,持續(xù)更新學(xué)習(xí)心得筆記

[Runtime 10種用法(沒(méi)有比這更全的了)](http://www.lxweimin.com/p/3182646001d1)

[成為iOS頂尖高手,你必須來(lái)這里(這里有最好的開(kāi)源項(xiàng)目和文章)](http://www.lxweimin.com/p/8dda0caf47ea)

[iOS逆向Reveal查看任意app 的界面](http://www.lxweimin.com/p/060745d5ecc2)

[JSPatch (實(shí)時(shí)修復(fù)App Store bug)學(xué)習(xí)(一)](http://www.lxweimin.com/p/344db07a2374)

[iOS 高級(jí)工程師是怎么進(jìn)階的(補(bǔ)充版20+點(diǎn))](http://www.lxweimin.com/p/1f2907512046)

[擴(kuò)大按鈕(UIButton)點(diǎn)擊范圍(隨意方向擴(kuò)展哦)](http://www.lxweimin.com/p/ce2d3191224f)

[最簡(jiǎn)單的免證書(shū)真機(jī)調(diào)試(原創(chuàng))](http://www.lxweimin.com/p/c724e6282819)

[通過(guò)分析微信app,學(xué)學(xué)如何使用@2x,@3x圖片](http://www.lxweimin.com/p/99f1f924ae45)

[TableView之MVVM與MVC之對(duì)比](http://www.lxweimin.com/p/d690b5d97201)

[使用MVVM減少控制器代碼實(shí)戰(zhàn)(減少56%)](http://www.lxweimin.com/p/f85363c82ea1)

[ReactiveCocoa添加cocoapods 配置圖文教程及坑總結(jié)](http://www.lxweimin.com/p/66f0c7e1ced8)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 對(duì)于從事 iOS 開(kāi)發(fā)人員來(lái)說(shuō),所有的人都會(huì)答出【runtime 是運(yùn)行時(shí)】什么情況下用runtime?大部分人能...
    夢(mèng)夜繁星閱讀 3,732評(píng)論 7 64
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,284評(píng)論 25 708
  • 我在最舒適的季節(jié),鳥(niǎo)語(yǔ)花香的春天,思索著自己到底怎么了,生活的重心哪去了,工作生活學(xué)習(xí)的動(dòng)力是什么?
    圓覺(jué)經(jīng)閱讀 163評(píng)論 0 0
  • 自從經(jīng)歷過(guò)上次斷舍離,不得不說(shuō),我深深地愛(ài)上了這項(xiàng)新的“活動(dòng)”。扔了生活中的東西之后,這一次,我向陪伴了自己好多年...
    膽小的鱷魚(yú)閱讀 596評(píng)論 0 3
  • 朋友圈里原來(lái)沒(méi)那么多人,現(xiàn)在越來(lái)越熱鬧了。 有些目不暇接。 之前的朋友圈是安樂(lè)窩,現(xiàn)在的朋友圈是大觀園。 非常熱鬧...
    溫迪畫(huà)畫(huà)閱讀 390評(píng)論 3 3