objective-c的消息到底是如何实现发送的呢?
在objective-c中,类、对象和方法都是一个c的结构体。从objc/objc.h头文件中我们可以找到他们的定义:
对象:
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};
类:
类方法列表:
单个实例方法结构体:
objc_method_list本质上是一个有objc_method元素的可变数组。一个objc_method结构体中有函数名,也就是SEL,有表示函数类型的字符串,以及函数的实现IMP.
发送一条消息之后,objc_msgSend做了什么事?objc_msgSend(obj, foo)例子来说,
1.首先通过对象的isa指针找到它的class
2.在class的method list找foo
3.如果没找到,就在它的父类中找foo
4.一单找到foo函数,就去执行它的IMP。
但这种实现有问题,效率低。一个class往往只有20%的函数会被经常调用,可能占纵调用次数的80%。每个消息都要遍历一遍objc_method_list并不合理。如果把经常调用的方法缓存起来,可以大大提高函数的查询效率。这也就是objc_method_list的objc_cache做的事情-找到foo后,把foo对应的method_name作为键,method_IMP作为值给存起来。当再次收到foo消息的时候,可以直接在cache里边找到,避免去遍历objc_method_list。