美文网首页
OC底层05.1:类方法生成位置

OC底层05.1:类方法生成位置

作者: ZAREMYDREAM | 来源:发表于2020-09-15 15:24 被阅读0次

    消失的类方法

    类结构中,我们说了如何通过地址偏移查找类相关信息。但是,如果我们在Person类中添加一个类方法,你会发现无法在类信息中找到。

    @interface Person : NSObject 
    @property (nonatomic, copy) NSString *name;
    - (void)run;
    + (void)find;
    @end
    @implementation Person
    - (void)run {
        
    };
    + (void)find {
        
    };
    

    通过上一章的方法查看methods,无法找到类方法+(void)find

    类方法获取

    Runtime中为我们提供了获取方法的函数class_getInstanceMethodclass_getClassMethod
    我们先来看看Runtime是怎么拿到类方法的。

    Method class_getClassMethod(Class cls, SEL sel)
    {
        if (!cls  ||  !sel) return nil;
    
        return class_getInstanceMethod(cls->getMeta(), sel);
    }
    
    Class getMeta() {
        if (isMetaClass()) return (Class)this;
        else return this->ISA();
    }
    

    一目了然,系统获取类方法就是通过(cls->getMeta())获取元类的class_getInstanceMethod实例方法。并且如果该类为元类的话,就是获取自己的实例方法。所以,类方法信息应该是存在元类中,我们可以验证一下


    可以发现,类方法的确存储在元类中

    拓展 - 面试 以下输出结果是什么

    //@interface Person : NSObject 
    //- (void)run;
    //+ (void)find;
    //@end
    
    void getmethod (Class cls){
        const char *className = class_getName(cls);
        Class metaCls = objc_getMetaClass(className);
        
        Method method1 = class_getInstanceMethod(cls, @selector(run));
        Method method2 = class_getInstanceMethod(metaCls, @selector(run));
        
        Method method3 = class_getClassMethod(cls, @selector(find));
        Method method4 = class_getClassMethod(metaCls, @selector(find));
        Method method5 = class_getInstanceMethod(metaCls, @selector(find));
        NSLog(@"\nmethod1:%p\nmethod2:%p\nmethod3:%p\nmethod4:%p\nmethod5:%p\n",method1,method2,method3,method4,method5);
    }
    

    运行结果如图:

    原因

    • 实例方法是存在对应中,元类中没有,所以method1找到,method2没找到。
    • 类方法存在元类中,所以method5能找到。
    • class_getClassMethod本身是去元类中找实例方法,所以method3能找到。
    • 元类class_getClassMethod是在自身的实例方法中找,所以method4能找到。

    相关文章

      网友评论

          本文标题:OC底层05.1:类方法生成位置

          本文链接:https://www.haomeiwen.com/subject/gxrfyktx.html