isKindOfClass VS isMemberOfClass 各自有对应的实例方法和类方法,源码如下:
+ (BOOL)isMemberOfClass:(Class)cls {
// 元类 VS 类
return object_getClass((id)self) == cls;
}
- (BOOL)isMemberOfClass:(Class)cls {
return [self class] == cls;
}
+ (BOOL)isKindOfClass:(Class)cls {
// for (int i= 0; i<10; i++) {
// }
// NSObject元类 vs NSObject类
// 元类的父类 - NSObject vs NSObject
// LGPerson元类 vs LGPerson
// NSObject vs LGPerson
//**object_getClass** 返回对应的**元类**
for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
- (BOOL)isKindOfClass:(Class)cls {
// 类 - NSObject 类 vs 父类 nil
for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
验证:
void test3() {
// 此处都调用对应的 + 类方法
BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]]; // 1
BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]]; // 0
BOOL re3 = [(id)[LGPerson class] isKindOfClass:[LGPerson class]]; // 0
BOOL re4 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]]; // 0
NSLog(@" re1 :%hhd\n re2 :%hhd\n re3 :%hhd\n re4 :%hhd\n",re1,re2,re3,re4);
// 此处都调用对应的 -实例方法
BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]]; // 1
BOOL re6 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]]; // 1
BOOL re7 = [(id)[LGPerson alloc] isKindOfClass:[LGPerson class]]; // 1
BOOL re8 = [(id)[LGPerson alloc] isMemberOfClass:[LGPerson class]]; // 1
NSLog(@" re5 :%hhd\n re6 :%hhd\n re7 :%hhd\n re8 :%hhd\n",re5,re6,re7,re8);
}
总结:
isKindOfClass的方法都进行了for循环查找父类的历程,-实例方法查找当前类的父类,+类方法查找元类的父类进行比较。PS:NSObject元类的父类是NSObject,NSObject的父类是nil。
isMemberOfClass实例方法是当前类与cls的比较,类方法是元类与cls的比较。