Effective Objective-C: Item11 Understand Role of obj_msgSend笔记

本文是笔者阅读《Effective Objective-C》时对Item 11部分内容的翻译,以作为个人学习笔记。

Item 11: Understand the Role of objc_msgSend

本节的重点是obj_msgSend函数,该函数是Objective-C消息传递机制中的核心部分。

消息传递是编写程序时我们最经常做的事,Objective-C作为C的超集,要了解它,首先要了解C语言静态绑定和动态绑定。

静态绑定意味着在编译时就已经知道要调用哪个方法了。比如如下代码:

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

但是如果写成下面这个样子:

#import <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();  
    return 0;  
} 

这里就用到了动态绑定,在运行之前调用哪一个函数是未知的。这两个例子的区别就在,第二个例子中只有一个函数调用,并且只有在运行时再去读取函数的地址而不是被编写成死的代码。

而Objective-C中消息传递就是由动态绑定实现的,所有的方法在底层都是由C函数实现的,在消息传递时调用哪个方法都是在运行时决定的。这种机制也使得Objective-C成了真正的动态语言。

消息传递的一般形式如下:

id returnValue = [someObject messageName:parameter]; 
someObject表示接收器,messgeName表示选择器,parameter就是参数了。

在底层编译器就会将其转化成为标准的C函数objc_msgSend,原型如下:

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

这个函数会从接受者的方法列表中寻找与选择器名称匹配的方法,找到后就会跳到实现部分。

调用形式如下:

id returnValue = objc_msgSend(someObject,  
                              @selector(messageName:),  
                              parameter); 
另外,objc_msgSend会将结果保存到一个快表里,以便未来的消息能够迅速找到对应的类和选择器。因此 这种方式不会比静态绑定慢很多。

处理其他情况的Objective-C运行时方法还有:

objc_msgSend_stret

用来发送返回结构体的消息。

objc_msgSend_fpret

用来发送返回浮点数的消息。

objc_msgSend_Super

用来向超类发送消息。

而之所以objc_msgSend能够在找到匹配的函数后就跳转过去是因为Objective-C中所有的类的方法都可以视为一个C函数,原型如下:

<return_type> Class_selector(id self, SEL _cmd, ...)
名称可能有所不同,这样写是为了方便解释其结构。每个类中都由一张表指向这些函数,objc_msgSend就利用这张表进行跳转。

并且其中还利用了"尾部优化"机制。这种机制当函数最终操作是调用另一个函数时使用。编译器会生成跳转向下一个函数的指令码,而不是在栈中再插入栈帧。当然只有当函数最后一项操作是调用其他函数,而且不会将返回值另作它用时才会使用“尾部优化”。


最后Things To Remember:

消息由接收器,选择器和参数构成,消息传递与方法调用等价。

所有的消息传递都由动态消息调度系统实现,形式如上所言。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值