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 不会向父类去找,就找你自己来比较