runtime - 面试题系列2 - isKindOf 和isMemberOf,isSubclassOf

这两者直接看源码就好了,在NSObject.mm这个文件里面

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

+ (BOOL)isSubclassOfClass:(Class)cls {
    for (Class tcls = self; tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}

这就是五个定义,可以看的出来isMember就是判断是否是当前类,而isKindOf和isSubclassOfClass会考虑是否是父类

 Person *person = [[Person alloc] init];
 NSLog(@"%d",[person isKindOfClass:[Person class]]);      //1
 NSLog(@"%d",[person isKindOfClass:[NSObject class]]);    //1
 NSLog(@"%d",[person isMemberOfClass:[Person class]]);    //1
 NSLog(@"%d",[person isMemberOfClass:[NSObject class]]);  //0
 NSLog(@"%d",[Person isSubclassOfClass:[Person class]]);  //1
 NSLog(@"%d",[Person isSubclassOfClass:[NSObject class]]);//1

所以如果只想判断是否是Person就用isMember,如果是它的父类也行就用其它两个

再说说类对象调用的,isSubclassOf就不说了,因为它并不会调用元类对象,而isMemberOf和isKindOf的类方法是会再调用一次isa指针的指向,类对象的指针指向的是元类对象

NSLog(@"%d",[Person isMemberOfClass:[Person class]]);   //0

所以这段代码毫无疑问的是false,因为比对的是类对象和类对象,而实际,源码会访问元类对象

NSLog(@"%d",[Person isMemberOfClass:object_getClass([Person class])]);  //1

而用元类去对比就没问题了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值