isKindOfClass 与 isMemberOfClass 有什么区别?

image.png

Test

        Person *per = [Person new];
        
        /*
        实例方法里面的self,是对象的首地址。 类方法里面的self,是Class。
        源码for循环中 NSObject的isa是NSObject元类,metaNSObject不等于NSObject.class类对象。
        然后取NSObject元类的superclass是NSObject类对象,等于NSObject.class类对象
        */
        BOOL res1 = [NSObject.class isKindOfClass:NSObject.class];//YES
        BOOL res2 = [NSObject.class isMemberOfClass:NSObject.class];//NO
        BOOL res3 = [Person.class isKindOfClass:Person.class];//NO
        BOOL res4 = [Person.class isMemberOfClass:Person.class];//NO
        
        BOOL res5 = [per isMemberOfClass:NSObject.class];//NO
        BOOL res6 = [per isKindOfClass:NSObject.class];//YES
        BOOL res7 = [per isMemberOfClass:Person.class];//YES
        BOOL res8 = [per isKindOfClass:Person.class];//YES

源码

类方法
+ (BOOL)isKindOfClass:(Class)cls {
    // obj->getIsa().superclass == cls
    for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}

+ (BOOL)isMemberOfClass:(Class)cls {
    return object_getClass((id)self) == cls;
}

Class object_getClass(id obj)
{
    if (obj) return obj->getIsa();
    else return Nil;
}
对象方法
- (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}
- (BOOL)isMemberOfClass:(Class)cls {
    return [self class] == cls;
}

总结

per.class返回的是per对象的isa指针,指向对象所属的类。
Person.class返回的是类对象本身。

NSObject的superclass等于nil。
NSObject类对象的元类的superclass指向NSObject类对象。
NSObject类对象的元类的isa指针指向该元类本身。

自定义类的元类的isa指向NSObject的元类。

你可能感兴趣的:(isKindOfClass 与 isMemberOfClass 有什么区别?)