isKindOfClass和isMemberOfClass的区别你知道吗

428 阅读2分钟

面试题

BOOL res1 = [[NSObject alloc] isMemberOfClass:[NSObject class]];

BOOL res2 = [[NSObject alloc] isKindOfClass:[NSObject class]];

BOOL res3 = [[Student alloc]  isMemberOfClass:[Person class]];

BOOL res4 = [[Student alloc]  isKindOfClass:[Person class]];

NSLog(@"res1:%d", res1);

NSLog(@"res2:%d", res2);

NSLog(@"res3:%d", res3);

NSLog(@"res4:%d", res4);

上面的Student的父类是Person,求结果。

BOOL res5 = [[NSObject class] isMemberOfClass:[NSObject class]];

BOOL res6 = [[NSObject class] isKindOfClass:[NSObject class]];

BOOL res7 = [[Student class] isMemberOfClass:[Person class]];

BOOL res8 = [[Student class] isKindOfClass:[Person class]];

NSLog(@"res5:%d", res5);

NSLog(@"res6:%d", res6);

NSLog(@"res7:%d", res7);

NSLog(@"res8:%d", res8);

这里和上面又有点不一样,之前左边是对象,这里是类。

答案

直接公共答案吧:1101 0100,怎样,和你想的是一样吗?

那我们就一起来探究下吧。

isMemberOfClass

- (BOOL)isMemberOfClass:(Class)cls {
    return [self class] == cls;
}
BOOL res1 = [[NSObject alloc] isMemberOfClass:[NSObject class]];

分析res1NSObject对象的类class是不是就是NSObject类。所以res1为true。

BOOL res3 = [[Student alloc]  isMemberOfClass:[Person class]];

分析res3Student对象的类class是不是就是Student类,而不是Person类。所以res3为false。

+ (BOOL)isMemberOfClass:(Class)cls {
    return self->ISA() == cls;
}
BOOL res5 = [[NSObject class] isMemberOfClass:[NSObject class]];

分析res5NSObject类的ISA指向是NSObject元类,那右边应该是object_getClassName([NSObject class])才对。所以res5为false。

BOOL res7 = [[Student class] isMemberOfClass:[Person class]];

分析res7Student类的ISA指向是Student元类,而不是Person类。所以res7为false。

isKindOfClass

- (BOOL)isKindOfClass:(Class)cls {

    for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {

        if (tcls == cls) return YES;

    }

    return NO;
}
BOOL res2 = [[NSObject alloc] isKindOfClass:[NSObject class]];

分析res2NSObject对象的类class是不是就是NSObject类,for循环一进来就对了。所以res2为true。

BOOL res4 = [[Student alloc]  isKindOfClass:[Person class]];

分析res4Student对象的类class是不是就是Student类,tcls->superclass是不是就找到Person类。所以res4为true。

+ (BOOL)isSubclassOfClass:(Class)cls {

    for (Class tcls = self; tcls; tcls = tcls->superclass) {

        if (tcls == cls) return YES;

    }

    return NO;
}
BOOL res6 = [[NSObject class] isKindOfClass:[NSObject class]];

分析res6NSObject类的ISA指向是NSObject元类,NSObject元类的父类是NSObject类。所以res6为true。

BOOL res8 = [[Student class] isKindOfClass:[Person class]];

分析res8Student类的ISA指向是Student元类,Student元类的父类是Person元类,而不是Person类。所以res8为false。

区别

从上面分析,我们已经知道这两个的用法了,它们的区别主要是isKindOfClass是有遍历以上父类,而isMemberOfClass直接是找到自己对应的class就行。

我们谨记一点就可以灵活运用它们,我们创建的对象的isKindOfClass或者isMemberOfClass是类,类的isKindOfClass或者isMemberOfClass是元类。