OC-消息发送机制

在Objective-C中,消息直到运行时才绑定到方法实现上。下面来看看消息发送具体是怎么样的。

新建一个helloClass类在 helloClass 类里面定义一个实例方法和一个类方法:

helloClass类

新建一个 HelloWorldClass 的类,继承自 HelloClass 类,在里面写一个helloWorldMethod方法:

HelloWorldClass类

通过clang命令:

$ clang -rewrite-legacy-objc HelloWorldClass.m

得到 helloWorldMethod方法C++代码:

C++HelloWorldClass类

首先,我们看下 helloWorldMethod 方法C++代码中两个参数,这两个参数在OC方法中是隐藏的,第一个参数是调用该方法的对象,第二个参数就是该方法的SEL。

在运行时,消息绑定到方法实现上,编译器将方法调用转换为objc_msgSend,参考向实例对象发送 helloInstanceMethod 消息:

objc_msgSend(obj, sel_registerName("helloInstanceMethod"))

当我们obj对象初始化的时候,也就是初始化了obj 结构体 objc_class。

当我们向obj对象发送helloInstanceMethod消息时,objc_msgSend函数通过obj对象中的isa指针获取到类的结构体,先从方法缓存方法列表cache methodLists中寻找,找到了调用对应函数实现;如果没有找到,再从方法列表methodLists里面找,如果找不到,一直沿着继承树往基类找;基类中如果没有就会走消息转发、动态方法解析(后面会讲)。

消息发送机制

前面说过类也是对象,向类对象发送消息的流程和向实例对象发送消息的流程是一样的,这里不细说。

当我们向父类发送消息时,参考向super发送 helloInstanceMethod 消息,使用的是objc_msgSendSuper函数:

objc_msgSendSuper(struct objc_super *super, SEL op, ...)

它的第一个参数是一个指向objc_super 结构体的指针,objc_super结构体在objc/message.h中的定义如下:

/// Specifies the superclass of an instance. 
struct objc_super {
/// Specifies an instance of a class.
__unsafe_unretained id receiver;

/// Specifies the particular superclass of the instance to message. 
#if !defined(__cplusplus)  &&  !__OBJC2__
/* For compatibility with old objc-runtime.h header */
__unsafe_unretained Class class;
#else
__unsafe_unretained Class super_class;
#endif
/* super_class is the first class to search */
};
#endif

一共有二个参数,第一个是消息接受的实例,第二个是父类。helloInstanceMethod中的objc_super结构第一个参数传入的self,第二个参数最后得到父类HelloClass。使用super编译器标示符发送消息实际上和self发送消息的机制是一样的,只是去父类的方法列表中找该方法。

最后使用clang命令

$ clang -rewrite-objc HelloWorldClass.m

发现一些关于元类的细节:

元类

前面说的元类的东西一直没有看到,在这个里面证明了”OC-类和对象”里面的那张isa游走图。

根据这张图可以推断出来HelloWorldClass类的isa指针指向HelloWorldClass的元类,而HelloWorldClass的元类的isa指针执行的是基类NSObject的元类。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值