The objc_msgSend Function
在objective-C里,在運行時前,消息并不和方法實現綁定.也就是說,在運行前只知道方法名,并不知道方法具體實現(方法體).
編繹器會把
[receiver message]
轉成
objc_msgSend(receiver, selector)
如果有參數
objc_msgSend(receiver, selector, arg1, arg2, ...)
這個消息方法做以下的動態綁定:
1.這會先找到這個selector所對應的方法實現(方法體).
2.它會把接收方法的對象以及所有參數傳入方法實現.
3.最后,它把程序的最后的計算結果,作回return 值傳回.
注意:編譯器會生成消息傳遞方法(objc_msgSend),你自己決不能直接調用.
每一個類結構(class structure)包含兩部分:
1:一個指向你類的指針.
2:一個類 分配表(dispatch table).這個表,應該是鍵值對應關系,鍵是方法selector,值是方法具體實現的地址.通過個地址可以找到方法體.
當一個新對象創建時,內存會被分配,并且它的實例亦是也會被初始化.第一個對象變量是指向對它類結構(class structure)的指針.這個指針被叫作 "isa",讓對象能訪問它的類,通過類,能訪問所有它繼承的類.
"isa" 是struct objc_object類型的指針
方法的層級調用,
當一個方法傳給對象,對象會通知道isa找到類結構,類結構里有dispatch table,在table里找selector,如果沒找到,會找父類的dispatch table.直到找到或到達NSObject.一旦找到方法就會調用,并傳入接收c對象的數據結構.
為了加快消息傳遞的進程,每個類都有自己的緩存,它可以包含繼承的方法,就像這個方法是在本類里定義的一樣.在搜索dispatch table之間,會先檢查接收方法的類的方法緩存,如果有就直接調用,速度只比一個函數調用稍微慢一些.一旦一個工程運行的足夠長,它所有的方法都在緩存里找到.緩存大小也會動態的增加,以至于可以容納親的消息.
當objc_msgSend找到方法的具體實現,它會調用程序并傳入所有的參數.這個包含兩個隱藏的參數
1:接收對象本身.
2:方法的selector