前言
Object-C是一門動態(tài)語言,Rumtime更是OC動態(tài)特性中最重要的一部分,今天我們就來深入了解一下 Runtime中的消息傳遞機制
首先我們要區(qū)分兩個概念,編譯時,運行時
編譯時:編譯時只是對語言進行最基本的檢查報錯,包括詞法分析、語法分析等等 我們?nèi)粘i_發(fā)中用的 OC 、 Swift、 Java 等等都是高級語言,(高級語言 可閱讀性強)但是不被計算機識別,所以編譯就可以把高級語言編譯成計算機可識別的匯編語言 系統(tǒng)所識別的二進制 ,但是編譯成功 不代表可以運行。
運行時:運行時即程序通過了編譯之后編譯好的代碼被裝載到內(nèi)存中跑起來的階段,這個時候會具體對類型進行檢查,而不僅僅是對代碼的簡單掃描分析,此時若出錯程序會崩潰。
現(xiàn)在我創(chuàng)建了一個TestClass的類 定義了一個名為run的實例方法沒有在.M中實現(xiàn) 。然后在main函數(shù)中調(diào)用,很顯然在編譯時沒有沒有報錯。
#import <Foundation/Foundation.h>
@interface TestClass : NSObject
- (void)run;
@end
int main(int argc, char * argv[]) {
@autoreleasepool {
TestClass *class =[[TestClass alloc]init];
[class run];
}
}
雖然沒有對應(yīng)run方法的實現(xiàn),但是編譯通過了,并沒有爆出錯誤,從而證明OC的動態(tài)特性, 方法的實際調(diào)用是在運行時進行的,通過動態(tài)綁定機制來決定需要調(diào)用的方法。
objc_msgSend()函數(shù)
void objc_msgSend(id self, SEL cmd, ...)
在OC中調(diào)用方法 我們可以看做就是給某個對象發(fā)送消息 而objc_msgSend()函數(shù)就是其中最核心的發(fā)送消息函數(shù)
這是一個參數(shù)個數(shù)可變的函數(shù)。能接收兩個或兩個以上的參數(shù),第一個參數(shù)代表接受者,第二個參數(shù)代表方法名。后續(xù)參數(shù)就是消息中的那些參數(shù),其順序不變。接受者就是調(diào)用方法的對象或者類(本質(zhì)上類也是對象,叫做類對象)。運行時,上面Objc的方法調(diào)用會被翻譯成一條C語言的函數(shù)調(diào)用,如下:
objc_msgSend(class, @selector(run))
消息傳遞流程
當調(diào)用objc_msgSend()函數(shù)會經(jīng)歷以下過程
1.從緩存中查找對應(yīng)SEL(封裝后方法名)的IMP (指向函數(shù)實現(xiàn)的指針)
被調(diào)用過的方法會存在緩存里面,每個類都會有一個表來存被調(diào)用過的方法,以便下次更快的調(diào)用。(這個是比較快速的)
2.從方法列表中查找
接受者會通過isa 找到自己的元類(metaClass),從元類的方法列表繼續(xù)查找對應(yīng)SEL(方法名)的IMP 如果找到則寫入緩存,調(diào)用。如果沒有找到再從父類中查找方法,如此往復(fù),直到達到基類。如果找不到則執(zhí)行方法的動態(tài)解析。
3.消息轉(zhuǎn)發(fā)機制--動態(tài)解析
調(diào)用
+ (BOOL)resolveInstanceMethod:(SEL)sel
方法來查看是否能夠返回一個selector,如果存在則返回selector。不存在進入下一步。
4.備用接受者
- (id)forwardingTargetForSelector:(SEL)aSelector
這個方法來詢問是否有接受者可以接受這個方法呀。如果有人接受,則交給它處理,就好像一切都沒發(fā)生過一樣。
5.完整轉(zhuǎn)發(fā)機制--消息重定向
如果到這一步還不能夠找到相應(yīng)的Selector的話,就要進行完整的方法轉(zhuǎn)發(fā)過程。調(diào)用方法
-(void)forwardInvocation:(NSInvocation *)anInvocation
最后還是沒有找到的話就會爆出unrecognized selector sent to instance 0x100111df0'的錯誤就來了。
以上就是消息傳遞機制的全部流程
至于第三步消息轉(zhuǎn)發(fā)機制的詳細流程會在之后的文章詳細說明 最后放上一張關(guān)于元類(metaClass)的詳細關(guān)系圖
