从objc_msgsend入手有两个参数id(消息接受者)、sel(方法编号)
runtime调用
- Objective-C: Selector调用
- NSObject:performSelector调用
- runtime的api调用
一些总结
- 父类对象方法要从父类方法列表进行查找
- 父类类方法要去父类元类方法列表查找
- 父类的类方法调用主体是Class
- super调用父类方法,是告诉系统从父类方法列表查找,但调用主体仍旧是self
快速查找就是自从cache_t中查找缓存,缓存名字查找结束。否则开始做慢速查找前的准备工作,并跳转到慢速查找流程
慢速查找
关键函数
IMP lookUpImpOrForward(id inst, SEL sel, Class cls, int behavior)
{
/if (curClass->cache.isConstantOptimizedCache(/* strict */true)) {
#if CONFIG_USE_PREOPT_CACHES
imp = cache_getImp(curClass, sel);
if (imp) goto done_unlock;
curClass = curClass->cache.preoptFallbackClass();
#endif
} else {
// curClass method list.
//通过本方法的方法列表查找,如果找到meth直接返回
method_t *meth = getMethodNoSuper_nolock(curClass, sel);
if (meth) {
imp = meth->imp(false);
goto done;
}
//递归查找父类方法
if (slowpath((curClass = curClass->getSuperclass()) == nil)) {
// No implementation found, and method resolver didn't help.
// Use forwarding.
imp = forward_imp;
break;
}
}
}
log_and_fill_cache
填充缓存
慢速查找是从本类查找到父类,再到NSObject的方法查找,先找本类方法列表,找到填充缓存,找不到去父类缓存和方法列表,找到缓存,找不到去转发
面试题:子类可以调用类方法实现NSObject的对象方法
验证
@implementation NSObject (GX)
//分类声明
- (void)instanceMethod{
NSLog(@"%s--我是对象方法",__func__);
}
@end
调用
//验证子类类方法调用 nsob对象方法
[GGXPerson instanceMethod];
类方法调用,GGXPerson的类方法存在其元类,最后找到根元类方法调用,如果没有对应类方法实现,根元类supper指向NSObject,去查找NSObkect方法列表。
网友评论