ios的訊息機制 以及 動態性質

2021-07-02 21:12:58 字數 1934 閱讀 5157

大部分的語言 使用的是 靜態繫結的函式呼叫方式。這種方式 在編譯階段就確定了執行時候需要呼叫的函式。而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 是基於執行緒的,每個執行緒都有乙個預設的訊息佇列,這個佇列相關聯於訊息中心,每個訊息中心或執行緒可以關聯於多個佇列。訊息中心是採用同步方式 訊息佇列...