OC底层05.2:isKindOfClass 与 isMemberOfClass

先来看看一道常见的面试题:

void isKindOfAndisMemeberOf() {
    BOOL b1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
    BOOL b2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
    BOOL b3 = [(id)[Person class] isKindOfClass:[Person class]];
    BOOL b4 = [(id)[Person class] isMemberOfClass:[Person class]];
    
    BOOL b5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];
    BOOL b6 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];
    BOOL b7 = [(id)[Person alloc] isKindOfClass:[Person class]];
    BOOL b8 = [(id)[Person alloc] isKindOfClass:[Person class]];
    
    NSLog(@"\n%hhd\n%hhd\n%hhd\n%hhd\n%hhd\n%hhd\n%hhd\n%hhd\n",b1,b2,b3,b4,b5,b6,b7,b8);
}

要想知道输出结果为什么,必须先知道isKindOfClass与isMemberOfClass的具体实现。

+ (BOOL)isMemberOfClass:(Class)cls {
    return self->ISA() == cls;
}

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

+ (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = self->ISA(); 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;
}

解析

  1. + (BOOL)isKindOfClass:(Class)cls实现判断元类是不是为当前类,再判断元类的父类是不是当前类,依次判断下去。所以:
  • NSObject的元类为根元类不同于NSObject,根元类的父类为NSObjectNSObject相同,所以b1true
  • Person的元类为Person(元类)不同,Person(元类)的父类为根元类不同,根元类的父类为NSObject不同,NSObject父类为nil不同,所以b3false
  1. + (BOOL)isMemberOfClass:(Class)cls是去和元类做比较,元类不同,所以b2b4false

3.- (BOOL)isKindOfClass:(Class)cls- (BOOL)isMemberOfClass:(Class)cls,都是判断实例对象的类是不是对应的类,区别在于isKindOf会往父类找,所以b5b8都为true

运行结果如图

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。