讀李峰峰博客筆記之RunTime消息發送

消息

  • 體會蘋果官方文檔中的 messages aren’t bound to method implementations until Runtime。消息直到運行時才會與方法實現進行綁定。
    • 我理解的是:源碼通過預處理 ->編譯->鏈接->匯編->生成可執行文件,在由shell(暫且理解為shell)解釋執行的時候才與方法的實現進行綁定,
    • 如何綁定:如果是實例方法每個實例的isa指針指向該實例對應的類,在這個類中有一個分發表,在這個表中存儲著一個SEL(理解為方法編號)對應一個IMP(函數指針),通過SEL找到對應的IMP,再將IP指針指向該函數地址執行

1、objc_msgSend

  • 這里要清楚一點,objc_msgSend 方法看起來好像返回了數據,其實objc_msgSend 從不返回數據,而是你的方法在運行時** 實現 ** ** 被調用后 **才會返回數據。下面詳細敘述消息發送的步驟(如下圖):

消息轉發順序

  1. 首先檢測這個* selector *是不是要忽略,比如 Mac OS X 開發,有了垃圾回收就不理會 retain,release 這些函數。
  • 檢測這個 selector 的 target 是不是 nil,Objc 允許我們對一個 nil 對象執行任何方法不會 Crash,因為運行時會被忽略掉

  • 如果上面兩步都通過了,那么就開始查找這個類的實現 IMP,先從 cache 里查找,如果找到了就運行對應的函數去執行相應的代碼。

  • 如果 cache 找不到就找類的方法列表中是否有對應的方法。

  • 如果類的方法列表中找不到就到父類的方法列表中查找,一直找到 NSObject 類為止。

  • 如果還找不到,就要開始進入動態方法解析了

  • 消息轉發函數,編譯器會根據情況在以下四個方法中選擇一個調用

/** 如果消息是傳遞給父類,那么會調用名字帶有 Super 的函數,如果消息返回值是數據結構而不是簡單值時,會調用名字帶有 stret 的函數。 */
objc_msgSend
objc_msgSend_stret
objc_msgSendSuper
objc_msgSendSuper_stret

2、方法中的隱藏參數

  • ** 我們經常用到關鍵字 self ,但是 self 是如何獲取當前方法的對象呢? **
    其實,這也是 Runtime 系統的作用,self 實在方法運行時被動態傳入的。當 objc_msgSend 找到方法對應實現時,它將直接調用該方法實現,并將消息中所有參數都傳遞給方法實現,同時,它還將傳遞兩個隱藏參數:
  • 接受消息的對象(self 所指向的內容,當前方法的對象指針)
  • 方法選擇器(_cmd 指向的內容,當前方法的 SEL 指針)
    這兩個參數中, self更實用。它是在** 方法實現中 訪問 消息接收者對象 的實例變量的 途徑 **(不是很理解)

3、獲取方法的地址

  • NSObject 類中有一個實例方法:methodForSelector,你可以用它來獲取某個方法選擇器對應的 IMP ,舉個例子:
/* 定義一個函數指針 */
void (*setter)(id, SEL, BOOL);
int i;
/* 給函數指針賦值 */
setter = (void (*)(id, SEL, BOOL))[target methodForSelector:@selector(setFilled:)];
/* 通過函數指針調用1000次這個方法 */
for ( i = 0 ; i < 1000 ; i++ ){
    setter(targetList[i], @selector(setFilled:), YES);
}

** 注意:上面用到的methodForSelector:方法是由 Runtime 系統提供的,而不是 Objc 自身的特性 **

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 轉至元數據結尾創建: 董瀟偉,最新修改于: 十二月 23, 2016 轉至元數據起始第一章:isa和Class一....
    40c0490e5268閱讀 1,789評論 0 9
  • 前言 runtime其實在我們日常開發過程中很少使用到,尤其是像我現在比較初級的程序猿就更用不到了。但是去面試很多...
    WolfTin閱讀 673評論 0 2
  • 消息發送和轉發流程可以概括為:消息發送(Messaging)是 Runtime 通過 selector 快速查找 ...
    lylaut閱讀 1,898評論 2 3
  • ——春天的主旋律 孤燈煢煢照書卷,秋意寒。 淚欲滴。夜靜。月未央。 何處嗚咽聲。凄凄。 猜忌已暗...
    春天的主旋律閱讀 277評論 0 1
  • 重復的沒有列出, 法語(英語)。 French (English) 1 Pardon (Excuse me) 2 ...
    layilayo閱讀 679評論 0 2