对象方法的调用就是向这个对象发送消息
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则结束,否则就继续进行缓存查找-->当前类查找-->父类逐级查找的流程)
- 如果一直查到根类依然没有查找到,则进入到消息转发流程中,完成消息传递
网友评论