Runtime消息发送

对象方法的调用就是向这个对象发送消息

typedef struct objc_method *Method;
struct objc_method {
    SEL method_name                                          OBJC2_UNAVAILABLE;
    char *method_types                                       OBJC2_UNAVAILABLE;
    IMP method_imp                                           OBJC2_UNAVAILABLE;
}

objc_method这个结构体的内容:

  • SEL method_name 方法名
  • char *method_types 方法类型
  • IMP method_imp 方法实现

消息格式

objc_msgSend("对象","SEL","参数"...)

寻找IMP的过程:

先从当前class的cache方法列表(cache methodLists)里去找。
如果找到了,跳到对应函数实现。
如果没找到,就从class的方法列表(methodLists)里找。
如果还找不到,就到super class的方法列表里找,直到找到基类(NSObject)为止。
最后再找不到,就会进入动态方法解析和消息转发的机制。

消息传递的流程:缓存查找-->当前类查找-->父类逐级查找

  • 类对象存储实例方法列表等信息
  • 元类对象存储类方法列表等信息

详细过程

  • 调用方法之前,先去查找缓存,看看缓存中是否有对应选择器的方法实现,如果有,就去调用函数,完成消息传递(缓存查找:给定值SEL,目标是查找对应bucket_t中的IMP,哈希查找)
  • 如果缓存中没有,会根据当前实例的isa指针查找当前类对象的方法列表,看看是否有同样名称的方法 ,如果找到,就去调用函数,完成消息传递(当前类中查找:对于已排序好的方法列表,采用二分查找,对于没有排序好的列表,采用一般遍历)
  • 如果当前类对象的方法列表没有,就会逐级父类方法列表中查找,如果找到,就去调用函数,完成消息传递(父类逐级查找:先判断父类是否为nil,为nil则结束,否则就继续进行缓存查找-->当前类查找-->父类逐级查找的流程)
  • 如果一直查到根类依然没有查找到,则进入到消息转发流程中,完成消息传递
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容