20期_iOS_方法查找流程分析

2023-08-21  本文已影响0人  萧修

从objc_msgsend入手有两个参数id(消息接受者)、sel(方法编号)

runtime调用

一些总结

快速查找就是自从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方法列表。

上一篇 下一篇

猜你喜欢

热点阅读