在Objective-C中,函数的调用最终都会转为成消息发送,objc_msgSend即为这个负责消息发送的函数。通常这个工作是由编译器来完成的,在代码中,我们可以尝试直接调用objc_msgSend来完成消息的发送。
对于一个给定的函数调用,如
[self SendImage:fileName];
可以通过如下方法来替换:
void (*action)(id, SEL, NSString*) = (void (*)(id, SEL, NSString*))objc_msgSend;
action(self, @selector(SendImage:), fileName);
其中,void (action)(id, SEL, NSString)定义了一个函数指针action,函数的输入值为(id, SEL, NSString)。(void ()(id, SEL, NSString*))objc_msgSend则将objc_msgSend转换为相应的函数指针,并赋值给action。
注意objc_msgSend函数总是以一个id变量和一个selector作为它的前两个参数。objc_msgSend 被转换成函数指针后,就可以通过这个函数指针进行函数调用了。
message.h的源码中给出了如下警告:
/* Basic Messaging Primitives
*
* On some architectures, use objc_msgSend_stret for some struct return types.
* On some architectures, use objc_msgSend_fpret for some float return types.
* On some architectures, use objc_msgSend_fp2ret for some float return types.
*
* These functions must be cast to an appropriate function pointer type
* before being called.
*/
对于不同架构(armv7 arm64等等),可能需要调用不同的objc_msgSend函数。因此函数中最好不要直接调用objc_msgSend函数,这一些列甄别转发的功能交给编译器来完成就行了。