對于Objective-C runtime的淺薄認知(二)

在上一篇runtime中我們了解到了對象, 類的結(jié)構體定義,了解到元類的定義, 對象,類結(jié)構體中isa指針的指向等,這篇我們將進入實戰(zhàn),該篇對于在編碼過程中有很大的幫助,減少項目中的代碼量黎侈。
1.關聯(lián)對象(Associated Object)
關聯(lián)對象類適用于動態(tài)添加屬性, 我們利用OC的運行時特性,在分類中添加一個屬性.我們可以把關聯(lián)對象想象成一個OC的對象(如字典), 這個對象通過給定的key連接到這個類的實例上, 由于使用的是C接口, 所以key是一個void指針(const void *). 我們還需要指定的一個內(nèi)存管理策略, 用來確定如何管理這個對象的內(nèi)存, 管理內(nèi)存的策略, 我相信很多人都見過下面的枚舉


屏幕快照 2016-06-21 上午11.34.32.png

當宿主對象被釋放時,會根據(jù)指定的內(nèi)存管理策略來處理管理對象. 如果指定的策略是assgin, 則宿主釋放的時候, 關聯(lián)對象不會被釋放; 如果指定是retain或者copy, 當宿主對象釋放時候, 關聯(lián)對象也會被釋放. 當然我們也可以考慮線程安全這個因素

屏幕快照 2016-06-21 下午1.41.26.png
屏幕快照 2016-06-21 下午1.41.12.png

首先,我們來看個例子, 如果我們創(chuàng)建一個UIButton對象, 會使用addTarget:這個方法添加action, 但是這么寫太過于繁瑣, 我們可以新建一個UIButton的分類, 給定一個block屬性, 在該分類的.m文件中重寫該屬性的setter和getter方法, 首先setter方法中添加關聯(lián)對象, 如果該對象已經(jīng)有SEL方法, 先移除, 然后給self添加方法; 之后再getter方法中利用objc_getAssociatedObject(self, cvenies_btnActionKey)獲取該屬性,在利用Target...Action添加的方法中使用block, 則可以完成block回調(diào)需要處理的方法, 此后, 再創(chuàng)建UIButton對象之后, 可以直接利用buttonObject.blockBtnAction = ^(UIButton *sender) {}這個方法處理點擊方法了.當然, 這只是runtime添加屬性簡單的實現(xiàn), 也可以動態(tài)添加手勢等屬性, 根據(jù)自己的需要構建不同的分類.

2.Method Swizzling
首先,我們來了解一下Method Swizzling的定義, 所謂Method swizzling指的是改變一個已存在的選擇器對應的實現(xiàn)的過程,它依賴于Objectvie-C中方法的調(diào)用能夠在運行時進改變——通過改變類的調(diào)度表(dispatch table)中選擇器到最終函數(shù)間的映射關系闷游。
同樣, 我們通過一個例子來引入Method Swizzling的用處, 對于一個大型的項目, 會有很多方向的部門并行開發(fā), 而且很多大公司都在堅持敏捷開發(fā)的原則, 對于更新迭代很快的項目, 會存在很多的控制器, 當出現(xiàn)bug的時候, 可能會難以尋找代碼所在的控制器, 這時候我們需要追蹤定位頁面所在的控制器, 會在viewWillAppear方法中添加 NSLog(@"當前控制器類名稱:%@", [[self class] description]); 這樣一段代碼用于打印當前控制器的名字, 當然會用以下3種方法可供參考, 我們來逐條分析:
(1)最笨的方法, 在每個控制器的viewWillAppear中都添加 NSLog(@"當前控制器類名稱:%@", [[self class] description]); 這樣一段代碼, 控制器中代碼量會不斷加重, 所以這是種最垃圾的處理方法;
(2)創(chuàng)建一個BaseViewController, 在BaseViewController的viewWillAppear方法中添加 NSLog(@"當前控制器類名稱:%@", [[self class] description]); 這樣一段代碼, 所有項目中的控制器都繼承自BaseViewController, 這是一種相對不錯的方法
(3)最后我們來嘗試一下Method Swizzling


屏幕快照 2016-06-21 下午2.51.22.png

使用Method Swizzling需要注意幾點:
<1>Swizzling應該在+load方法中實現(xiàn)峻汉。
每個類的這兩個方法會被Objective-C運行時系統(tǒng)自動調(diào)用贴汪,+load是在一個類最開始加載時調(diào)用,+initialize是在應用中第一次調(diào)用該類或它的實例的方式之前調(diào)用休吠。這兩個方法都是可選的扳埂,只有實現(xiàn)了才會被執(zhí)行。

因為method swizzling會影響全局瘤礁,所以減少冒險情況就很重要阳懂。+load能夠保證在類初始化的時候就會被加載,這為改變系統(tǒng)行為提供了一些統(tǒng)一性柜思。但+initialize并不能保證在什么時候被調(diào)用——事實上也有可能永遠也不會被調(diào)用岩调,例如應用程序從未直接的給該類發(fā)送消息。
<2>使用dispatch_once方法, 是為了保證該控制器只被創(chuàng)建一次.
使用Method Swizzling相對于上面的兩種給人更加裝逼的感覺, 當然我們知道Method Swizzling的具體實現(xiàn)才是最重要的.
關于Objective-C中runtime還有更多的黑魔法值得我們?nèi)ヌ剿? 一定要好好的研究底層的實現(xiàn), 才是我們掌握一門語言的關鍵...

代碼參考:https://github.com/CveniEs/CveniEsSchema.git

文章參考:南峰子的技術博客
CocoaChina/Method Swizzling專題

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末赡盘,一起剝皮案震驚了整個濱河市号枕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌陨享,老刑警劉巖葱淳,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異抛姑,居然都是意外死亡赞厕,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門定硝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來皿桑,“玉大人,你說我怎么就攤上這事喷斋⊙涠荆” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵星爪,是天一觀的道長。 經(jīng)常有香客問我粉私,道長顽腾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任诺核,我火速辦了婚禮抄肖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘窖杀。我一直安慰自己漓摩,他們只是感情好,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布入客。 她就那樣靜靜地躺著管毙,像睡著了一般腿椎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上夭咬,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天啃炸,我揣著相機與錄音,去河邊找鬼卓舵。 笑死南用,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的掏湾。 我是一名探鬼主播裹虫,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼融击!你這毒婦竟也來了筑公?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤砚嘴,失蹤者是張志新(化名)和其女友劉穎十酣,沒想到半個月后拘鞋,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體落剪,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年主卫,在試婚紗的時候發(fā)現(xiàn)自己被綠了工育。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片虾宇。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖如绸,靈堂內(nèi)的尸體忽然破棺而出嘱朽,到底是詐尸還是另有隱情,我是刑警寧澤怔接,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布搪泳,位于F島的核電站,受9級特大地震影響扼脐,放射性物質(zhì)發(fā)生泄漏岸军。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一瓦侮、第九天 我趴在偏房一處隱蔽的房頂上張望艰赞。 院中可真熱鬧,春花似錦肚吏、人聲如沸方妖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽党觅。三九已至雌澄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間仔役,已是汗流浹背掷伙。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留又兵,地道東北人任柜。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像沛厨,于是被迫代替她去往敵國和親宙地。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353

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