1. 思考如下代码的输出
int main(int argc, const char * argv[]) {
BOOL b1 = [[YYPerson class] isKindOfClass:[YYPerson class]];
BOOL b2 = [[YYPerson class] isMemberOfClass:[YYPerson class]];
BOOL b3 = [[NSObject class] isKindOfClass:[NSObject class]];
BOOL b4 = [[NSObject class] isMemberOfClass:[NSObject class]];
NSLog(@"%d, %d, %d, %d", b1, b2, b3, b4);
return 0;
}
以上代码输出:0, 0, 1, 0
2. 同样的原理,我们回答问题之前,先要知道 isKindOfClass 和 isMemberOfClass 底层到底调用了什么方法?
//类调用
+ (BOOL)isMemberOfClass:(Class)cls {
return object_getClass((id)self) == cls;
}
或者
+ (BOOL)isMemberOfClass:(Class)cls {
return self->ISA() == cls;
}
- (BOOL)isMemberOfClass:(Class)cls {
return [self class] == cls;
}
===================================================
+ (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
或者
+ (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;
}
1.类方法和实例方法的区别:实例方法[self class]拿的是类对象 ,类方法objc_getClass(self)拿的是元类对象。
2.isMemberOfClass:只会对比当前对象是否和目标对象相等; isKindOfClass:会查找当前对象以及它的父类对象中有没有和目标对象相等的;
练习一
int main(int argc, const char * argv[]) {
YYPerson *person = [[YYPerson alloc] init];
NSLog(@"%d", [person isMemberOfClass:[YYPerson class]]);
NSLog(@"%d", [person isMemberOfClass:[NSObject class]]);
NSLog(@"%d", [person isKindOfClass:[YYPerson class]]);
NSLog(@"%d", [person isKindOfClass:[NSObject class]]);
return 0;
}
===
Demo[16964:980177] 1 // 1 等价于: [person class] == [YYPerson class]
Demo[16964:980177] 0 // 0 等价于: [person class] == [NSObject class]
Demo[16964:980177] 1 // 1 等价于: YYPerson类对象以及父类对象 == YYPerson类对象
Demo[16964:980177] 1 // 1 等价于: YYPerson类对象以及父类对象 == NSObject类对象
练习二
int main(int argc, const char * argv[]) {
NSLog(@"%d", [YYPerson isMemberOfClass:object_getClass([YYPerson class])]);
NSLog(@"%d", [YYPerson isKindOfClass:object_getClass([NSObject class])]);
return 0;
}
====
Demo[17167:991810] 1 // 1 等价于: YYPerson元类对象 == YYPerson元类对象
Demo[17167:991810] 1 // 1 等价于: YYPerson元类对象以及父元类对象 == NSObject元类对象
练习三
int main(int argc, const char * argv[]) {
NSLog(@"%d", [[YYPerson class] isKindOfClass:[YYPerson class]]);
NSLog(@"%d", [[YYPerson class] isMemberOfClass:[YYPerson class]]);
NSLog(@"%d", [[NSObject class] isKindOfClass:[NSObject class]]);
NSLog(@"%d", [[NSObject class] isMemberOfClass:[NSObject class]]);
return 0;
}
===
Demo[16797:971234] 0 // 0 等价于: YYPerson的元类以及父元类 == YYPerson的类对象
Demo[16797:971234] 0 // 0 等价于: YYPerson的元类 == YYPerson的类对象
Demo[16797:971234] 1 // 1 等价于: NSObject的元类以及父元类 == NSObject的类对象 (根元类superclass 指向 NSObject的类对象)
Demo[16797:971234] 0 // 0 等价于: NSObject的元类 == NSObject的类对象