Method Swzzling,是指runtime的一個(gè)API方法

使用runtime的這個(gè)交換方法結(jié)合分類category可以改變系統(tǒng)本身的方法,在系統(tǒng)本身方法的基礎(chǔ)上增加代碼操作。
比方說(shuō)一個(gè)項(xiàng)目基本搭建完畢后,我們想在用戶每一次進(jìn)入控制器的時(shí)候都做一個(gè)標(biāo)記,統(tǒng)計(jì)這個(gè)用戶進(jìn)入了多少次這個(gè)控制器。但是整個(gè)項(xiàng)目中控制器都非常多,全在viewdidload中要寫(xiě)的代碼多而且工作量大。用繼承的方法創(chuàng)建一個(gè)基類可以滿足需求,但是要修改的還是很多,而且之后的控制器還需要繼承這個(gè)類。
Method swizzing配合類別可以實(shí)現(xiàn)在不干擾其它工程代碼的情況下為系統(tǒng)的方法添加功能。
按照上面的那個(gè)需求,我們要為所有控制器的viewdidload添加一個(gè)記錄用戶點(diǎn)擊次數(shù)的功能。
新建一個(gè)UIViewController的類別。在.m中做了這樣的事情

并不需要導(dǎo)入這個(gè)分類的頭文件。在類文件剛被加載(程序啟動(dòng)前)就會(huì)調(diào)用,我們將兩個(gè)對(duì)象方法進(jìn)行了交換。系統(tǒng)的viewDidLoad和自定義的FlagDidLoad方法。即所有控制器在調(diào)用viewDidLoad的時(shí)候都會(huì)進(jìn)入到flagDidLoad當(dāng)中,flagDidload里面又發(fā)現(xiàn)了flagDIdload方法,因?yàn)樽隽私粨Q,這時(shí)候控制器會(huì)執(zhí)行本身的viewDidLoad方法,不會(huì)發(fā)生死循環(huán)。
到目前為止,我們約等于什么事情都沒(méi)做。程序運(yùn)行起來(lái)走的方法跟之前一模一樣。但是我們?cè)趂lagDidLoad下方可以添加自己想要的功能了。比方說(shuō)打印一個(gè)coming。這時(shí)候整個(gè)程序中只要有控制器調(diào)用viewDidLoad方法,控制臺(tái)都會(huì)打印一條coming.

接下來(lái)的事情想必大家也知道了。每次進(jìn)入控制器做個(gè)標(biāo)記,把NSlog換作記錄的方法即可。

運(yùn)行幾次之后控制臺(tái)的輸出。接下來(lái)根據(jù)業(yè)務(wù)需求處理數(shù)據(jù)就好了。

如果我們想給某幾個(gè)特定的控制器做記錄,隨意加判斷了。

我們通過(guò)Method Swizzing給系統(tǒng)的viewdidload添加功能,使整個(gè)項(xiàng)目中的Viewdidload方法下面都不用新增代碼了。同理其它系統(tǒng)方法也可以用類似的方法。
比方說(shuō)有些項(xiàng)目是完全自定義導(dǎo)航欄的,每一個(gè)控制器的導(dǎo)航欄都是隱藏掉的,在各個(gè)控制器的viewWillAppear中可能都寫(xiě)了[self.navigationController.navigationBarsetHidden:YES];這個(gè)方法。
這個(gè)時(shí)候我們也可以用交換方法,統(tǒng)一給所有控制器viewWillAppear添加這個(gè)隱藏的方法。
參考:http://www.cocoachina.com/ios/20160121/15076.html