1. 程式人生 > >OC的訊息機制

OC的訊息機制

OC的訊息機制

系統內部都是靠objc_msgSend來實現方法呼叫的在Objective-C中,message與方法的真正實現是在執行階段繫結的,而非編譯階段,編譯器會將訊息傳送轉換成objc_msgSend 方法的呼叫。objc_msgSend方法含有兩個必要引數:receiver、 方法名(即selector)。如:[receiver message]; 將被轉換為: objc_msgSend(receiver selector); objc_msgSend方法也 能hold住message引數,如:objc_msgSend(receiver ,selector, arg1,arg2,…);

objc_msgSend方法會按照順序進行以下操作, 以完成動態繫結:查詢selector所指代的程式(方法的真正實 現)。因為不同類對同一方法有不同的實現,所以對方法的真正 實現的查詢依賴於receiver的類呼叫該實現,並將一系列引數 傳遞過去將實現的返回值作為自己的返回值,返回值訊息傳遞 的關鍵是,編譯器構建每個類和物件所採用的資料結構、每個 類都包含以下兩個必要元素:一個指向父類的指標一個排程表 ( d i s p a t c h t a b l e )。 該 調 度 表 將 類 的 s e l e c t o r 與 方 法 的 實 際 內 存地址關聯起來。每個物件都有一個指向所屬類的指標isa。通過該指標,物件可以找到它所屬的類,也就找到了其全部父類。

Runtime 如何通過selector找到相對應的IMP地址?
:類物件中有類方法和例項方法的列表,列表中記錄著方法名,引數,和方法實現(例項方法存在於類物件中,類方法存在於元類方法中).
SEL就是方法名,IMP就是implementation,是指向方法實現函式的指標.
舉個例子說明一下SEL和IMP的關係:以一本書的目錄為例,SEL就是文章名 IMP就是對應的頁碼 。
當發訊息時,如果是例項方法,會通過isa去類物件中的方法列表中查詢對應的IMP,如果是類方法,會通過isa去元類物件中的方法列表中查詢對應的IMP。

參考這篇文章[https://www.jianshu.com/p/21e2d9da313b

]