美文网首页OC底层原理
isMemberOfClass 和 isKindOfClass

isMemberOfClass 和 isKindOfClass

作者: 只写Bug程序猿 | 来源:发表于2020-02-07 22:35 被阅读0次

    看一个例子

     BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];//1
     BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];// 0
     BOOL re3 = [(id)[LGPerson class] isKindOfClass:[LGPerson class]];//0
     BOOL re4 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]];// 0
     NSLog(@"\n re1 :%hhd\n re2 :%hhd\n re3 :%hhd\n re4 :%hhd\n",re1,re2,re3,re4);
    
     BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];//1
     BOOL re6 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];// 1
     BOOL re7 = [(id)[LGPerson alloc] isKindOfClass:[LGPerson class]];//1
     BOOL re8 = [(id)[LGPerson alloc] isMemberOfClass:[LGPerson class]];// 1
     NSLog(@"\n re5 :%hhd\n re6 :%hhd\n re7 :%hhd\n re8 :%hhd\n",re5,re6,re7,re8);
    

    打印结果为: 1000 1111

    解析

    话不多说直接上源码

    + (BOOL)isMemberOfClass:(Class)cls {
        return object_getClass((id)self) == cls;
    }
    
    - (BOOL)isMemberOfClass:(Class)cls {
        return [self class] == cls;
    }
    
    + (BOOL)isKindOfClass:(Class)cls {
        for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->superclass) {
            if (tcls == cls) return YES;
        }
        return NO;
    }
    
    - (BOOL)isKindOfClass:(Class)cls {
        for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
            if (tcls == cls) return YES;
        }
        return NO;
    }
    
    BOOL re4 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]];// 0
    

    因为这里并没有进行alloc所以我们这里调用的静态方法+ (BOOL)isMemberOfClass:(Class)cls

    那么看object_getClass((id)self)得到一个什么玩意儿

    Class object_getClass(id obj)
    {
        if (obj) return obj->getIsa();
        else return Nil;
    }
    

    我们可以看出这里获取的是objisa,也就是元类(mete Class),而我们传进来的是一个 Person类,显然是不相等的所以这里打印结果为false

    同样+ (BOOL)isKindOfClass:(Class)cls是通过一个for循环来进行对比判断
    Person继承自NSObject.所以Person的元类的父类为根源类,也就是NSObject的元类
    而我们传进来的clsPerson类,所以这里条件不满足返回false
    那么

     BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];//1
    

    为什么打印True呢,因为NSObject的元类的父类也为NSObject,满足条件所以打印True
    附上经典isa走位图

    image.png

    相关文章

      网友评论

        本文标题:isMemberOfClass 和 isKindOfClass

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