OC底层原理

isMemberOfClass 和 isKindOfClass

2020-02-07  本文已影响0人  只写Bug程序猿

看一个例子

 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
上一篇 下一篇

猜你喜欢

热点阅读