一起看源码-isKindOfClass 和isMemberOfClass的区别

相关链接:objc4-750配置下载教程
日常开发中,我们想必会经常通过isKindOfClass和isMemberOfClass去处理一些逻辑判断,但是我们真的了解它们吗?
话不多说我们直接上场景:

@interface Person : NSObject
@end
@implementation Person
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
        BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];

        BOOL re3 = [(id)[Person class] isKindOfClass:[Person class]];
        BOOL re4 = [(id)[Person class] isMemberOfClass:[Person class]];
        NSLog(@" re1 :%hhd re2 :%hhd re3 :%hhd re4 :%hhd ",re1,re2,re3,re4);
    }
    return 0;
}

输出结果:

2019-08-21 17:01:00.054439+0800 001-isKindOfClass&isMemberOfClass[25960:1615638]  re1 :1 re2 :0 re3 :0 re4 :0

接下来我们通过objc源码来分析为什么会是输出这个样的一个结果~

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

由源码得知:

在isKindOfClass中有一个循环,先判断当前类是否等于元类,不等就继续循环取元类的父类进行判断,不等再继续取父类,如此循环下去。

然而此时我们需要上isa走向图:


[NSObject class] 调用 isKindOfClass,第一次判断先判断NSObject 和 NSObject的元类是否相等,从图上我们也可以看出,NSObject的元类是根元类。接着第二次循环判断NSObject与根元类的父类是否相等。还是从那张图上面我们可以看到:根元类 的父类也就是NSObject本身。所以第二次循环相等,于是第一行res1输出应该为YES。

[Person class] 调用 isKindOfClass,第一次for循环,Person的元类与[Person class]不等,第二次for循环,Person元类的父类 指向的是 NSObject Meta Class(根元类), 和[Person class]不相等。第三次for循环,根元类指向的是NSObject,和 [Person Class] 不相等。第四次循环,NSObject Class 的父类 指向 nil, 和 Person Class不相等。第四次循环之后,退出循环,所以第三行的res3输出为NO。

isMemberOfClass的源码实现是拿到自己的isa指针和自己比较,是否相等。

第二行 isa 指向 NSObject 的 元类,所以和 NSObject不相等。第四行,isa指向Person的元类,和Perosn Class也不等,所以第二行res2和第四行res4都输出NO。

你可能感兴趣的:(一起看源码-isKindOfClass 和isMemberOfClass的区别)