大部分的語言 使用的是 靜態繫結的函式呼叫方式。這種方式 在編譯階段就確定了執行時候需要呼叫的函式。而objective-c 使用的是訊息傳遞機制。在執行的時候才會知道呼叫的函式。
實際上 ,底層都是c語言的。而c語言是函式呼叫方式。那麼 objectie-c的訊息響應機制是真麼實現的呢。其實 oc 中遇到訊息都會呼叫訊息傳遞機制中的核心函式。 objc_msgsend(id self ,sel,cmd, ...) 這個方法引數個數是變化的。接收2個或2個以上的引數。
第乙個引數是訊息接收者 第二個引數 就是具體的 selector 。然後 這個方法會嘗試到接受者這個物件的類中的方法列表 中尋找 sel。如果沒有找到會到繼承鏈往上查詢。如果一直沒有找到 就出發訊息**。
毫無疑問這個處理方法效能肯定不如靜態繫結的。好在 oc為每個類分配了一塊快取。用於存放以前匹配到的訊息。這個就是 快速對映表 。
上面的核心**函式 objc_msgsend 在一些特殊情況會分發到其他對應的方法上面去:
objc_msgsend_stret 處理返回是結構體同事 暫存器能夠容納下訊息大小的結構體
objc_msgsend_fpret 返回浮點數的訊息 為了處理 x86 等架構 cpu 浮點數 各種奇怪的狀況
objc_msgsendsuper 發給超類
當然細節有很多很多 我們不需要 完全知道。只要知道訊息響應機制。是有固定的 靜態繫結的 幾個c語言方法**實現的。
所謂方法列表。可以想象 每個 objective-c 物件的每個方法都可以視為簡單的c函式。每個類都有一張**。指標指向那些函式。而key 就是選擇的 selector。
當訊息派發過程中 沒有找到對應的 selector。 這時候 訊息**機制就出場了。
這裡分為3個部分
1.動態方法解析。
呼叫的方法為 +(bool)resolveinstancemethod:(sel) selector 例項方法
+(bool)resolveclassmethod:(sel) selector 類方法
返回 yes 就是說可以新增 當然 你需要實現邏輯。可以借助 runtime.h的函式
class_addmethod
這個方法表示是否能新增乙個例項方法用以處理這個 selector
首先會詢問所屬的類。能不能動態新增方法以處理這個 selector。
+(bool)resolveinstancemethod:(sel)sel
return [super resolveinstancemethod:sel];
}
imp 就是 函式的指標。 可以跟 sel 一起來理解。 sel 和 imp 可以看做是 上面提到的方法列表中的 key 和 value。當然 上面 還需要實現 autotest 方法。這是個普通c函式
void autotest(id self, sel _cmd)
2.備援接受者
如果不能新增函式 接下來 就會詢問 有沒有備援的接受者。
-(id
)forwardingtargetforselector:(
sel)aselector;
返回值就是備援的物件。沒有返回nil;
3.完整的訊息**機制。
到這裡 程式只能啟動完整的訊息**機制。執行期間將所有的細節都封裝到 nsinvocation 物件中。再給接受者最後一次機會。令其設法解決當前還未處理的這條訊息。這時候呼叫的是:
-(void
)forwardinvocation:(
nsinvocation
*)aninvocation;
當然 如果一直到nsobject 都沒有解決。就只能呼叫 doesnotrecognizeselector:來丟擲異常了
imp :個人感覺 runtime 裡面有很多方法都是在操作 方法列表。 就是在處理sel 跟 imp 來實現動態性質。
iOS高階 iOS訊息機制
靜態繫結,即在編譯時就直接將要呼叫函式的位址寫進去,醬紫就直接進入呼叫函式中,如下 中,編譯器在編譯的時候就已經知道程式中有printhello與printgoodbye兩個函式,遇事會直接生成呼叫這些函式的指令。import void printhello void printgoodbye vo...
IOS訊息分發(廣播)機制
在ios中,提供了通知機制 notification 可以在物件間傳遞和接受資訊。傳遞和接受資訊的物件間甚至不需要知道對方的存在。究其本質來說,其實是設計模式中的觀察者模式的應用。一種更好的方式,就是使用ios中的notification機制。notification由三部分組成 傳送訊息者 訊息中...
iOS訊息機制基於廣播模型
ios訊息機制基於廣播模型 訊息中心 nsnotificationcenter 是基於程序的單件例項 訊息佇列 nsnotificationqueue 是基於執行緒的,每個執行緒都有乙個預設的訊息佇列,這個佇列相關聯於訊息中心,每個訊息中心或執行緒可以關聯於多個佇列。訊息中心是採用同步方式 訊息佇列...