Objective C函式訊息機制的理解

2021-06-04 02:55:23 字數 1588 閱讀 3954

c語言中,函式呼叫過程:c語言中,編譯完成後,函式名就是指向函式入口的位址,呼叫函式就是直接執行這個位址的**。

而objectiv-c是間接的方式,函式呼叫是向類或者物件傳送訊息,比如:[myclass new],向myclass傳送訊息new,查詢myclass的訊息列表,如果找到new函式執行,myclass裡沒找到就去父類中繼續找,找不到就出錯。

通過這種訊息機制,objective-c也能實現多型。

sel型別

讓我們接著看「doproxy.h」檔案的下列**:

1id cattle[3];

2sel say;

3sel skin;

複製**

其中id cattle[3]定義了乙個陣列用於儲存cattle或者bull物件。這一行**估計大家都很熟悉,筆者就不贅述了。像這樣的傳統的陣列並不能完全滿足我們的需求,當我們需要做諸如追加,刪除等操作的時候,會很不方便。在隨後的章節裡面筆者將要向大家介紹傳統陣列的替代解決方案nsarray。

上一段**的第二行和第三行是本節所關注的,就是sel型別。objective-c在編譯的時候,會根據方法的名字(包括引數序列),生成乙個用 來區分這個方法的唯一的乙個id,這個id就是sel型別的。我們需要注意的是,只要方法的名字(包括引數序列)相同,那麼它們的id都是相同的。就是 說,不管是超類還是子類,不管是有沒有超類和子類的關係,只要名字相同那麼id就是一樣的。除了函式名字和id,編譯器當然還要把方法編譯成為機器可以執 行的**,這樣,在乙個編譯好的類裡面,就產生了如下圖所示方法的**示意圖(本構造屬於筆者推測,沒有得到官方證實,所以圖5-2為示意圖僅供參考,我們可以暫時認為是這樣的)。

圖5-2,方法的**示意圖 

請注意setskincolor後面有乙個冒號,因為它是帶引數的。由於存在這樣的乙個**,所以在程式執行的時候,我們可以方便的通過方法的名字,獲取到方法的id也就是我們所說的sel,反之亦然。具體的使用方法如下:

1sel 變數名 

=@selector(方法名字);

2sel 變數名 

=nsselectorfromstring(方法名字的字串);

3nsstring 

*變數名 

=nsstringfromselector(sel引數);

複製**

其中第1行是直接在程式裡面寫上方法的名字,第2行是寫上方法名字的字串,第3行是通過sel變數獲得方法的名字。我們得到了sel變數之後,可以通過下面的呼叫來給乙個物件傳送訊息:

[物件 performselector:sel變數 withobject:引數1 withobject:引數2];

這樣的機制大大的增加了我們的程式的靈活性,我們可以通過給乙個方法傳遞sel引數,讓這個方法動態的執行某乙個方法;我們也可以通過配置檔案指定需要執行的方法,程式讀取配置檔案之後把方法的字串翻譯成為sel變數然後給相應的物件傳送這個訊息。

從效率的角度上來說,執行的時候不是通過方法名字而是方法id也就是乙個整數來查詢方法,由於整數的查詢和匹配比字串要快得多,所以這樣可以在某種程度上提高執行的效率。 

Objective C 之Runtime訊息機制

最近在找工作,objective c中的runtime是經常被問到的乙個問題,幾乎是面試大公司必問的乙個問題。當然還有一些其他問題也幾乎必問,例如 runloop,block,記憶體管理等。其他的問題如果有機會我會在其他文章中介紹。本篇文章主要介紹runtime。runtime簡稱執行時。就是系統在...

objective c底層 runtime機制

runtime是oc的真面目。oc底層的一套c語言api.unsigned int count 獲取屬性列表 objc property t propertylist class copypropertylist self class count for unsigned int i 0 i 獲取方...

精通Objective C 物件和訊息傳遞

訊息傳遞 附錄前一章節建立的atom類 nsobject類中用於建立類例項 即物件 的方法 id alloc通過alloc方法,可以建立物件,下面以建立乙個atom物件為例 建立乙個屬於atom類的物件,並為它分配乙個資料型別為id的變數 id atom atom alloc 與上面語句等價,顯示定...