isMemberOfClass和isKindOfClass 区别

苹果的开源代码

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

object_getClass() 和class 说明

1.class方法返回对象的类对象
2.object_getClass()函数,就是返回这个对象的isa指针指向的对象
(对象为实例对象则isa指针指向类对象,对象为类对象则isa指针指向元类对象。)
所以我们不难看出
isMemberOfClass:(Class)aClass;方法的本质,就是判断左边对象的isa指针指向的对象与右边对象是否相等。
isKindOfClass:(Class)cls方法的本质就是判断左边对象的isa指针指向的对象或者isa指向对象的父类superClass是否与右边的对象相等

面试题:输出打印结果

@interface HPPeople : NSObject

@end

@implementation HPPeople

@end

@interface HPStudent : NSObject

@end

@implementation HPStudent

-(instancetype)init
{
    if (self = [super init]) {
        BOOL res1 = [[NSObject class] isKindOfClass:[NSObject class]];
        BOOL res2 = [[NSObject class] isMemberOfClass:[NSObject class]];
        BOOL res3 = [[HPPeople class] isKindOfClass:[NSObject class]];
        BOOL res4 = [[HPStudent class] isMemberOfClass:[NSObject class]];
        NSLog(@"%d,%d,%d,%d",res1,res2,res3,res4);
    }
    return self;
}

@end

正确输出为:1,0,0,0
首先判断res2和res4 左边类对象的isa指针指向元类对象MetaClass,元类对象MetaClass与右边的类对象明显不相等返回 NO,res3中HPPeople的元类对象MetaClass 及他的父类superClass 明显也不等于NSObjec的类对象故res3返回NO.
看到这里似乎res1也应该返回NO,但事实总是打脸,res1返回的是Yes。原因是NSObject的元类对象MetaClass的父类superClass就是[NSObject class]isKindofClass只要是满足左边的对象的isa指向的对象的superClass等于右边的对象就会返回Yes

你可能感兴趣的:(isMemberOfClass和isKindOfClass 区别)