美文网首页程序员
三:类内存结构--知识扩展

三:类内存结构--知识扩展

作者: Mr姜饼 | 来源:发表于2020-11-16 17:53 被阅读0次
    上课知识回顾:

    证明:对象方法存在类里面,类方法存在元类里面!!!!!


    源码分析:

    class_getInstanceMethod:获取类的对象方法!!

    Method class_getInstanceMethod(Class cls, SEL sel)
    {
        if (!cls  ||  !sel) return nil;
    
        // This deliberately avoids +initialize because it historically did so.
    
        // This implementation is a bit weird because it's the only place that 
        // wants a Method instead of an IMP.
    
    #warning fixme build and search caches
            
        // Search method lists, try method resolver, etc.
        lookUpImpOrForward(nil, sel, cls, LOOKUP_RESOLVER);
    
    #warning fixme build and search caches
    
        return _class_getMethod(cls, sel);
    }
    
    static Method _class_getMethod(Class cls, SEL sel)
    {
        mutex_locker_t lock(runtimeLock);
        return getMethod_nolock(cls, sel);
    }
    
    getMethod_nolock(Class cls, SEL sel)
    {
        method_t *m = nil;
    
        runtimeLock.assertLocked();
    
        // fixme nil cls?
        // fixme nil sel?
    
        ASSERT(cls->isRealized());
    
        while (cls  &&  ((m = getMethodNoSuper_nolock(cls, sel))) == nil) {
            cls = cls->superclass;
        }
    
        return m;
    }
    
    getMethodNoSuper_nolock(Class cls, SEL sel)
    {
        runtimeLock.assertLocked();
    
        ASSERT(cls->isRealized());
        // fixme nil cls? 
        // fixme nil sel?
    
        auto const methods = cls->data()->methods();
        for (auto mlists = methods.beginLists(),
                  end = methods.endLists();
             mlists != end;
             ++mlists)
        {
            // <rdar://problem/46904873> getMethodNoSuper_nolock is the hottest
            // caller of search_method_list, inlining it turns
            // getMethodNoSuper_nolock into a frame-less function and eliminates
            // any store from this codepath.
            method_t *m = search_method_list_inline(*mlists, sel);
            if (m) return m;
        }
    
        return nil;
    }
    

    核心代码:auto const methods = cls->data()->methods();

    ** 是不是验证了我们上节课对应的,取类的对象方法,即在data()->methods()中取,有的话返回地址,没有的话返回0

    源码分析:

    class_getClassMethod:获取类的类方法(等价于 获取该类 元类 的实例化方法)

    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();
        }
    

    总结: 获取一个类的类方法 其实等价于,获取该元类的实例化方法 (如果是元类的话,则不需要取该元类的元类了,直接返回,不继续递归了,不然的话会无限递归循环)


    结合上小节的实例lldb来分析:

    
    @interface LGPerson : NSObject
    {
        NSString* interst;
        
    }
    @property (nonatomic, copy) NSString *nickName;
    @property (nonatomic, strong) NSString *name;
    
    
    //对象方法
    - (void)test_InstanceMethod;
    //类方法
    + (void)test_ClassMethod;
    @end
    
    

    论证:

    1. Method method1 = class_getInstanceMethod([LGPerson Class], @selector(test_InstanceMethod));//有
    

    1 :LGPerson类拥有"test_InstanceMethod"的对象方法,所以此处 可以 得到结果

     Class metaClass = objc_getMetaClass("LGPerson");//获取元类
     Method method2 = class_getInstanceMethod(metaClass, @selector(test_InstanceMethod));//无
    

    2 :LGPerson类的 元类 没有"test_InstanceMethod"的对象方法,拥有类方法"test_ClassMethod"的方法,所以此处 不可以 得到结果

    Method method3 = class_getInstanceMethod([LGPerson Class], @selector(test_ClassMethod));//无
    

    3 :LGPerson类,没有类方法"test_ClassMethod"的方法,所以此处 不可以 得到结果

     Class metaClass = objc_getMetaClass("LGPerson");//获取元类
     Method method4 = class_getInstanceMethod(metaClass, @selector(test_ClassMethod));//有
    

    4 :LGPerson类的 元类 ,拥有类方法"test_ClassMethod"的方法,所以此处 可以 得到结果

    const char *className = class_getName([LGPerson Class]);
    Class metaClass = objc_getMetaClass(className);
    //得不到结果!
    Method method1 = class_getClassMethod(pClass, @selector(test_InstanceMethod));//无
    //得不到结果!
    Method method2 = class_getClassMethod(metaClass, @selector(test_InstanceMethod));//无
    
    //可以得到结果~
    Method method3 = class_getClassMethod(pClass, @selector(test_ClassMethod));//有
    //可以得到结果~(元类的话,则不需要取该元类的元类了,直接返回,不继续递归了,不然的话会无限递归循环)
    Method method4 = class_getClassMethod(metaClass, @selector(test_ClassMethod));//有
    

    源码分析:

    [Class isKindOfClass]: 类方法

    + (BOOL)isKindOfClass:(Class)cls {
    
        for (Class tcls = self->ISA(); tcls; tcls = tcls->superclass) {
            if (tcls == cls) return YES;
        }
        return NO;
    }
    

    初始赋值为该类的 “元类”,循环从该元类的父类找,直到找到该元类及其父类与参数cls等同的情况,才返回 “true”,否则返回“false”


    源码分析:

    [Class isMemberOfClass]:类方法

    + (BOOL)isMemberOfClass:(Class)cls {
        return self->ISA() == cls;
    }
    

    初始赋值为该类的 “元类”,判断该元类是否与参数“cls”等同,相同返回 “true”,否则返回“false”


    源码分析:

    [objc isKindOfClass]:对象方法

    - (BOOL)isKindOfClass:(Class)cls {
        for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
            if (tcls == cls) return YES;
        }
        return NO;
    }
    

    初始赋值为该“类“,循环从该类的父类找,直到找到该类及其父类与参数cls等同的情况,才返回 “true”,否则返回“false”


    源码分析:

    [objc isKindOfClass]:对象方法

    - (BOOL)isMemberOfClass:(Class)cls {
        return [self class] == cls;
    }
    

    初始赋值为该“类“,判断该类是否与参数cls等同,等同返回 “true”,否则返回“false”

    实战:
    BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]]; 
    

    1:此处调用"类方法",NSObject的"元类"不同于NSObject,跑循环之后可以找到与NSObject相同的类 ,所以此处为 ”true“

    BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
    

    2:此处调用"类方法",NSObject的"元类"不等同于NSObject,所以此处为 ”false“

    BOOL re3 = [(id)[LGPerson class] isKindOfClass:[LGPerson class]];
    

    3:此处调用"类方法",LGPerson的"元类"不等同于LGPerson,即使循环查找父类,也不存在等同的情况,所以此处为 ”false“

    BOOL re4 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]];
    

    4:此处调用"类方法",LGPerson的"元类"不等同于LGPerson,所以此处为 ”false“

    const char *className = class_getName(LGPerson.class);
    Class metaClass = objc_getMetaClass(className);
    BOOL re5 = [(id)[LGPerson class] isMemberOfClass:metaClass];     
    

    5:此处调用"类方法",LGPerson的"元类"不等同于LGPerson的元类,所以此处为 ”ture"

    BOOL re6 =  [(id)[LGPerson class] isKindOfClass:[NSObject class]];
    

    6:此处调用"类方法",LGPerson的"元类"虽然不等同于NSObject类,但是跑父类的循环,会找到与NSObject相同的类,所以此处为 ”ture"

    BOOL re7 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];       
    BOOL re8 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];    
    BOOL re9 = [(id)[LGPerson alloc] isKindOfClass:[LGPerson class]];     
    BOOL re10 = [(id)[LGPerson alloc] isMemberOfClass:[LGPerson class]];   
    

    7:true 8:true 9: true 10:true 不多说什么

    **记住:只要isMemberOfClass成立,则isKindOfClass 一定成立


    完结撒花✿✿ヽ(°▽°)ノ✿

    相关文章

      网友评论

        本文标题:三:类内存结构--知识扩展

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