国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

編寫高質量OC代碼52建議總結:11.理解objc_msgSend的作用(消息機制)

2019-11-09 15:41:05
字體:
來源:轉載
供稿:網友

在對象上調用方法,術語叫做“傳遞消息”,消息有“名稱”和“選擇器(方法)”,可以接收參數,還可能有返回值。OC是C的超集,C語言使用靜態綁定,在編譯期間就能決定運行時做調用的函數。

#include <stdio.h>void PRintHello() {    printf("hello, world!/n");}void printGoodbye() {    printf("Goodbye, world!/n");}void doTheThing(int type) {    if (type == 0) {        printHello();    } else {        printGoodbye();    }}編譯器在編譯代碼的時候就知道有printHello和printGoodbye兩個函數了,會直接生成調用這些函數的指令,函數地址實際上是硬編碼在指令之中。

#include <stdio.h>void printHello() {    printf("hello, world!/n");}void printGoodbye() {    printf("Goodbye, world!/n");}void doTheThing(int type) {    void (*fnc)();    if (type == 0) {        fnc = printHello;    } else {        fnc = printGoodbye;    }    fnc();}如果代碼變成這樣,就得使用“動態綁定”,因為所要調用的函數直到運行期才能確定,第一個例子中,if 和 else 中都有函數調用指令,第二個例子中只有一個函數調用指令,待調用的函數地址無法硬編碼在指令中,要在運行期讀取出來。

給對象發送消息可以這么寫:

id returnValue = [someObject messageName:parameter];someObject叫做“接受者”,messageName叫做“選擇器”,選擇器與參數合起來叫做“消息”。編譯器將上述語句轉換為C語言函數調用 “objc_msgSend”

void objc_msgSend(id self, SEL cmd, ...)這是個“參數個數可變的函數”,能接受兩個或兩個以上的參數。第一個參數代表接受者,第二個參數代表選擇器,后續參數是消息中的參數編譯器會把剛才的例子轉換為如下函數。

id returnValue = objc_msgSend(someObject, @selector(messageName:), parameter);objc_msgSend 會在接受者所屬的類中搜尋其“方法列表”,如果找到與“選擇器”名稱相符的代碼就實現,沒找到就延繼承體系向上查找,最終找不到,就實現“消息轉發”。

備注:每個類都有一塊緩存“快速映射表”,如果稍后還向該類發送相同的消息,執行就快。

運行環境中一些“邊界情況”,需要其他函數處理  1.objc_msgSend_stret:如果待發送的消息要返回結構體,交給這個函數。  2.objc_msgSend_fpre:如果消息返回的是浮點數,交給這個函數。  3.objc_msgSendSuper:給超類發消息,用這個函數。也有與objc_msgSend_fpre和objc_msgSend_fpre等效的處理超類消息的方法。 

OC對象的每個方法都可以看做簡單的C函數,原型如下:

<return_type> Class_selector(id self, SEL _cmd, ...)每個類里都會有一張表格,其中的指針都會指向這種函數,選擇器的名稱則是查表時用的“鍵”,objc_msgSend用這張表來尋找應該執行的方法并跳轉實現。   

“尾調用優化”:如果函數的最后一項操作是調用另外一個函數,編譯器會生成調轉至另一個函數所用的指令碼。不會向調用堆棧中推入新的“棧幀”。注意:只有當函數的最后一項操作僅僅是調用其他函數而不會將其返回值另做他用時


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 日土县| 东兰县| 珠海市| 南昌市| 凤庆县| 大田县| 东方市| 轮台县| 临江市| 庐江县| 增城市| 永和县| 通辽市| 策勒县| 德昌县| 育儿| 乐清市| 苍溪县| 鄂尔多斯市| 体育| 建宁县| 浏阳市| 宁津县| 广河县| 梨树县| 宜城市| 改则县| 资源县| 香格里拉县| 抚顺县| 白河县| 怀化市| 蒙城县| 阿拉尔市| 玉龙| 綦江县| 荃湾区| 思南县| 郯城县| 和平区| 多伦县|