1.消息機(jī)制
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)用。
[obj makeText];
首先,編譯器將代碼[obj makeText];轉(zhuǎn)化為objc_msgSend(obj, @selector (makeText));,在objc_msgSend函數(shù)中。首先通過(guò)obj的isa指針找到obj對(duì)應(yīng)的class。在Class中先去cache中 通過(guò)SEL查找對(duì)應(yīng)函數(shù)method(猜測(cè)cache中method列表是以SEL為key通過(guò)hash表來(lái)存儲(chǔ)的,這樣能提高函數(shù)查找速度),若 cache中未找到。再去methodList中查找,若methodlist中未找到,則取superClass中查找。若能找到,則將method加 入到cache中,以方便下次查找,并通過(guò)method中的函數(shù)指針跳轉(zhuǎn)到對(duì)應(yīng)的函數(shù)中去執(zhí)行。
2.消息轉(zhuǎn)發(fā)(可以間接實(shí)現(xiàn)多重繼承)
當(dāng)向someObject發(fā)送某消息,但runtime system在當(dāng)前類和父類中都找不到對(duì)應(yīng)方法的實(shí)現(xiàn)時(shí),runtime system并不會(huì)立即報(bào)錯(cuò)使程序崩潰,而是依次執(zhí)行下列步驟:

1.動(dòng)態(tài)方法解析:向當(dāng)前類發(fā)送 resolveInstanceMethod: 信號(hào),檢查是否動(dòng)態(tài)向該類添加了方法。(迷茫請(qǐng)搜索:@dynamic)
2.快速消息轉(zhuǎn)發(fā):檢查該類是否實(shí)現(xiàn)了 forwardingTargetForSelector: 方法,若實(shí)現(xiàn)了則調(diào)用這個(gè)方法。若該方法返回值對(duì)象非nil或非self,則向該返回對(duì)象重新發(fā)送消息。
3.標(biāo)準(zhǔn)消息轉(zhuǎn)發(fā):runtime發(fā)送methodSignatureForSelector:消息獲取Selector對(duì)應(yīng)的方法簽名。返回值非空則通過(guò)forwardInvocation:轉(zhuǎn)發(fā)消息,返回值為空則向當(dāng)前對(duì)象發(fā)送doesNotRecognizeSelector:消息,程序崩潰退出。
這里只對(duì)2進(jìn)行代碼演示:意思是說(shuō),本類實(shí)現(xiàn)不了的方法,可以轉(zhuǎn)發(fā)給別的類去實(shí)現(xiàn)

- (id)forwardingTargetForSelector:(SEL)aSelector
{
class*other = [classnew];if([other forwardingTargetForSelector:aSelector]) {returnother;
}else{return[super forwardingTargetForSelector:aSelector];
}
}
)
這樣如果本類中沒(méi)有的方法,就會(huì)去class中嘗試查找,如果有,則返回class對(duì)象,讓其執(zhí)行,這樣就實(shí)現(xiàn)了快速消息轉(zhuǎn)發(fā)