1.消息機(jī)制
因?yàn)镺bject-C時(shí)一門動(dòng)態(tài)語(yǔ)言,所以把一些決定工作從編譯連接推遲到運(yùn)行時(shí)。也就是說(shuō)使用一個(gè)對(duì)象調(diào)用一個(gè)方法指導(dǎo)運(yùn)行期才能確定。
比如
Person * person = [[Person alloc]init];
這一代碼是向編譯器發(fā)送一個(gè)創(chuàng)建person的對(duì)象并初始化的消息
當(dāng)編譯器看到這一個(gè)消息后先調(diào)用
Person * person = objc_msgSend(objc_getClass("Person"), sel_registerName(“alloc”));
然后在調(diào)用
objc_msgSend(person,sel_registerName(“init"));
2.Runtime 運(yùn)行時(shí)機(jī)制
我們平時(shí)使用OC所寫的代碼在運(yùn)行時(shí)都唄轉(zhuǎn)成了runtime中c語(yǔ)言的代碼
可以用 clang -rewrite-objc XX.m在終端生成一個(gè)XX.cpp文件進(jìn)行查看。
蘋果給我們提供了一套R(shí)untime的完整的Api

在開發(fā)中,我們經(jīng)常會(huì)使用runtime在程序運(yùn)行的過程,動(dòng)態(tài)的創(chuàng)建一個(gè)類/添加一個(gè)類的屬性/方法,修改屬性/方法
在使用runtime前需要了解的有2個(gè)點(diǎn):1.method代表的是方法;2.ivar表達(dá)的是成員變量。
2.1OC的序列化跟反序列化中的如何運(yùn)用rumtime
當(dāng)需要本地存儲(chǔ)的數(shù)據(jù)量較少的時(shí)候,我們可以使用傳統(tǒng)的方法進(jìn)行歸檔解檔:

但是當(dāng)屬性多的時(shí)候,這種方式寫起來(lái)就會(huì)有一些麻煩,而且代碼也比較丑陋所以我們可以使用runtime來(lái)節(jié)約我們代碼

上面代碼我們先獲取了這個(gè)類的成員變量列表,然后在一個(gè)for循環(huán)里面遍歷把取到的ivar轉(zhuǎn)成OC中的NSString,最后用KVC分別進(jìn)行取值跟賦值。
2.2利用runtime實(shí)現(xiàn)全屏側(cè)滑功能

因?yàn)槲覀冎老到y(tǒng)有一個(gè)側(cè)滑返回的手勢(shì),但是效果并不是我們需要的,所以我們自己創(chuàng)建一個(gè)手勢(shì)然后調(diào)用系統(tǒng)的方法就可以達(dá)到我們需要的目的。
2.3利用runtime修改系統(tǒng)的方法:利用鉤子(HOOK)原理在系統(tǒng)啟動(dòng)的時(shí)候修改我們想要修改的方法

load方法是加載這個(gè)文件就加載這個(gè)方法,比main方法還要早調(diào)用,所以在load方法里面拿到系統(tǒng)的imageName:方法跟我們自己寫的CatImageName:方法,然后把兩個(gè)方法進(jìn)行交換。
注意點(diǎn)是在CatImageName:里面如果還是調(diào)用系統(tǒng)的imageName:,因?yàn)閮蓚€(gè)方法已經(jīng)交換了,所以造成死循環(huán),重復(fù)在那里調(diào)用CatImageName:方法。