Effective Objective-C 2.0 — 第11條:理解 objc_msgSend 的做用

  • 消息由接受者、選擇子及參數構成。給某對象「發送消息」 (invoke a message) 也就至關於在該對象上「調用方法」(call a method)
  • 發給某對象的所有信息都要由「動態消息派發系統」(dynamic message dispatch system)來處理,該系統會查出對應的方法,並執行其代碼。

 

在對象上調用方法,也能夠叫作「傳遞消息」函數

消息:name 或 selector         能夠接受參數,並且還有返回值編碼

OC是C的超集,C 語言使用「靜態綁定」(static binding),即在編譯期就能決定運行時所應調用的函數。編譯器在編譯代碼的時候就已經知道程序中有printHello 與printGoodbye 這兩個函數了spa

#import <stdio.h>
void printHello() {
    printf ("Hello World!\n");
}
void printGoodbye() {
     pirntf ("Goodbye, World!\n");
}
void doTheThing(int type) {
    if (type == 0) {
    printHello ();
    } else {
        printGoodbye();
    }
    return 0;
}

如果這樣:prototype

#import <stdio.h>
void printHello() {
    printf ("Hello World!\n");
}
void printGoodbye() {
     pirntf ("Goodbye, World!\n");
}
void doTheThing(int type) {
    void (*fnc) ();
    if (type == 0) {
    fnc  =  printHello;
    } else {
        fnc  = printGoodbye;
    }
  fnc();  
    return 0;
}

這就是 動態綁定 (dynamic binding), 待調用的函數沒法硬編碼在指令之中,而是要在運行期讀取出來。指針

在Objective-C在中, 若是向某對象傳遞消息,那就會使用動態綁定機制來決定須要調用的方法。在底層都是普通的C語言函數, 然而對象受到消息以後,究竟該調用哪一個方法則徹底於運行期決定,甚至能夠在程序雲心時改變,這些特性使OC 稱爲一門真正動態語言code

給對象發送消息以下:對象

id returnValue = [someObject messageName:parameter];

someObject :接受者、receiverblog

messageName:選擇子、selectorcmd

選擇子與參數合起來稱爲」消息「(message)原型

編譯器將消息轉換成C語言函數調用,所調用函數乃是消失機制中的核心函數 objc-msgSend,其原型(prototype)以下:

void objc_msgSengd(id self, SEL cmd, ...)

第一個參數表明接受者,第二個參數表明選擇子(SEL是選擇子的類型)

id returnValue = objc_msgSend(someObject, @selector(messageName:), parameter);

其餘函數:

objc_msgSend_stret: 若是待發送的消息要返回結構體,那麼可交由此函數處理。

objc_msgSend_fpret:若是消息返回的是浮點數,可交由此函數處理。

objc_msgSendSuper:給超類發消息。

Objective-C 對象的每一個方法均可以視爲簡單的C函數 其原型:

<return_type> Class_selector(id self, SEL _cmd, ...)

每一個類都有一張表格,其中的指針都會指向這種函數,而選擇子的名稱則是查表時所用的「鍵」。   objc_msgSend等函數正是經過這張表格來尋找應該執行的方法並跳至其實現的。

相關文章
相關標籤/搜索