这两者直接看源码就好了,在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
而用元类去对比就没问题了