iOS底层系列之<20>--Runtime(八)isKindOfClass 和 isMemberOfClass

1、下面的打印结果是什么?

BOOL res1 = [[NSObject class] isKindOfClass:[NSObject class]];
BOOL res2 = [[NSObject class] isMemberOfClass:[NSObject class]];
BOOL res3 = [[Person class] isKindOfClass:[Person class]];
BOOL res4 = [[Person class] isMemberOfClass:[Person class]];
        
NSLog(@"%d %d %d %d",res1,res2,res3,res4); 

2、分析源码

+ (BOOL)isMemberOfClass:(Class)cls {
    // self->ISA(): 意思是获取自己的类对象,因为类的isa指向元类对象,下面同理
    // 即:传进来的类是否等于自己的元类对象
    return self->ISA() == cls; 
}

- (BOOL)isMemberOfClass:(Class)cls {
   // 判断当前的类是否和传进来的类相等
    return [self class] == cls;
}

+ (BOOL)isKindOfClass:(Class)cls {
    // 用自己的元类对象,和传进来的类作比较
    // 并且自己的元类对象还可以向上寻找父类对象,只要向上能找到,也返回YES
    // 总结:自己的元类对象或元类对象的父类,是否和传进来的类相等。
    for (Class tcls = self->ISA(); tcls; tcls = tcls->getSuperclass())
        if (tcls == cls) return YES;
    }
    return NO;
}

- (BOOL)isKindOfClass:(Class)cls {
    // 实例对象或实例对象的父类,是否等于传进来的类
    for (Class tcls = [self class]; tcls; tcls = tcls->getSuperclass()) {
        if (tcls == cls) return YES;
    }
    return NO;
}
  • 1、分析第一个情况 + (BOOL)isMemberOfClass:(Class)cls
// 类方法调用:所以不会相等
[[NSObject class] isMemberOfClass:[NSObject class]];   // 返回 NO

// 当类方法调用的时候,应该传入元类对象才会相等
[[NSObject class] isMemberOfClass:object_getClass([NSObject class])]; //  返回 YES
  • 2、分析第二个情况 - (BOOL)isMemberOfClass:(Class)cls
NSObject *obj = [[NSObject alloc] init];
[obj isMemberOfClass:[NSObject class]]; // 返回YES
// 因为这里是用对象方法调用,实例对象的类就是NSObject 类
// [obj class] == [NSObject class] 
// 所以返回YES
  • 3、分析第三个情况 + (BOOL)isKindOfClass:(Class)cls
// 首先 [NSObject class] 类的元类对象,还是自己: NSObject
// 其次 [NSObject class] 就是: NSObject
// 所以,这个特殊的调用,返回的是YES
[[NSObject class] isKindOfClass:[NSObject class]];  // 返回YES
//同理,只要是继承自NSObject的类,通过父类一层一层网上找,最后都会找到,返回YES,例如:
[[Person class] isKindOfClass:[NSObject class]]; // 也是返回YES

// 因为NSObject类的元类对象,指向的基类,就是NSObject类对象,所以当在for循环里面一层一层网上找,最后还是会相等,这个是一个比较特殊的地方
// 通过打印下面的可以证明
NSLog(@"object_getClass([NSObject class])] == %@",object_getClass([NSObject class]));
NSLog(@"[NSObject class] == %@",[NSObject class]);

// 打印结果:
object_getClass([NSObject class])] == NSObject
[NSObject class] == NSObject

-----------------------------------------------
// [Person class] 的元类对象是什么?是NSObject所以:
[[Person class] isKindOfClass:[Person class]]; // 返回NO

// 当这样改动一下,就会返回YES
[[Person class] isKindOfClass:[NSObject class]]; // 返回YES

  • 4、分析第四种情况 - (BOOL)isKindOfClass:(Class)cls
// 这个时候是对象方法,对象方法返回的就是用自己的类来比较
// person对象的类,就是Person

Person *person = [[Person alloc] init];
[person isKindOfClass:[Person class]]; // 返回YES

2、总结

1.实例对象的isa—> 类对象
2、类对象的isa --> 元类对象
3.元类对象,也是一种特殊的类对象
4.isKindOf 和 isMemberOf 首先都是用传进来的对象的isa去做判断
5.isKindOf 如果找不到,可以向父类去找,只要找到就行
6.isMemberOf 不会向父类去找,就找你自己来比较

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值