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

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

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

2019-11-09 14:32:55
字體:
供稿:網(wǎng)友

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

#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();    }}編譯器在編譯代碼的時(shí)候就知道有printHello和printGoodbye兩個(gè)函數(shù)了,會直接生成調(diào)用這些函數(shù)的指令,函數(shù)地址實(shí)際上是硬編碼在指令之中。

#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();}如果代碼變成這樣,就得使用“動(dòng)態(tài)綁定”,因?yàn)樗{(diào)用的函數(shù)直到運(yùn)行期才能確定,第一個(gè)例子中,if 和 else 中都有函數(shù)調(diào)用指令,第二個(gè)例子中只有一個(gè)函數(shù)調(diào)用指令,待調(diào)用的函數(shù)地址無法硬編碼在指令中,要在運(yùn)行期讀取出來。

給對象發(fā)送消息可以這么寫:

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

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

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

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

運(yùn)行環(huán)境中一些“邊界情況”,需要其他函數(shù)處理  1.objc_msgSend_stret:如果待發(fā)送的消息要返回結(jié)構(gòu)體,交給這個(gè)函數(shù)。  2.objc_msgSend_fpre:如果消息返回的是浮點(diǎn)數(shù),交給這個(gè)函數(shù)。  3.objc_msgSendSuper:給超類發(fā)消息,用這個(gè)函數(shù)。也有與objc_msgSend_fpre和objc_msgSend_fpre等效的處理超類消息的方法。 

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

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

“尾調(diào)用優(yōu)化”:如果函數(shù)的最后一項(xiàng)操作是調(diào)用另外一個(gè)函數(shù),編譯器會生成調(diào)轉(zhuǎn)至另一個(gè)函數(shù)所用的指令碼。不會向調(diào)用堆棧中推入新的“棧幀”。注意:只有當(dāng)函數(shù)的最后一項(xiàng)操作僅僅是調(diào)用其他函數(shù)而不會將其返回值另做他用時(shí)


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 铁力市| 曲松县| 桐庐县| 肥东县| 四川省| 武定县| 宁城县| 晋宁县| 日土县| 科技| 和田市| 乌兰浩特市| 顺义区| 准格尔旗| 澄江县| 栾川县| 龙泉市| 黔西县| 铁力市| 土默特左旗| 阿鲁科尔沁旗| 淮滨县| 偏关县| 吴桥县| 寿光市| 武宣县| 阿瓦提县| 简阳市| 张家港市| 渝中区| 贡嘎县| 广宁县| 晋江市| 德惠市| 马公市| 长乐市| 曲沃县| 兰坪| 遵化市| 宁陵县| 台湾省|