本文主要目的是分析二者之间的关系和区别:
- (BOOL)isKindOfClass:(Class)aClass;
- (BOOL)isMemberOfClass:(Class)aClass;
+ (BOOL)isKindOfClass:(Class)aClass;
+ (BOOL)isMemberOfClass:(Class)aClass;
划重点:此文章只讨论对象之间的比较
首先我们先来搞一下runtime的结构图
这个图就不赘述了,不是本文的重点。但是我们还是要先明确的概念:
类和元类打印对象结果名字虽然相同但是地址完全不同,这是2个内存地址
上源码:
+ (BOOL)isMemberOfClass:(Class)cls {
return self->ISA() == cls;
}
// self->ISA() 表示当前类型 返回的是一个Class
// cls 传入的类型
- (BOOL)isMemberOfClass:(Class)cls {
return [self class] == cls;
}
/**
- (Class)class {
return object_getClass(self);
}
[self class]返回的就是Class
**/
+ (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = self->ISA(); tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
/**
到了kind方法当中则是去循环判断
获取当前的ISA所指向的类,如果和当前类不想等,则去找他的父类
按照这个逻辑不停的向上循环,如果找到当前的类对象就返回成功,否则返回false
**/
- (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
/**
到了kind方法当中则是去循环判断
获取当前的类对象,如果和当前类不想等,则去找他的父类
按照这个逻辑不停的向上循环,如果找到当前的类对象就返回成功,否则返回false
**/
举个栗子, 我们就来分析接下来的源码
- (void)viewDidLoad {
[super viewDidLoad];
Person *person = [[Person alloc] init];
Man *man = [[Man alloc] init]; //Man是Person的子类
NSObject *obj = [[NSObject alloc] init];
//对象方法
if ([person isMemberOfClass:[Person class]]) {
NSLog(@"person isMemberOfClass: Person");
} else {
NSLog(@"person is't member of Person");
}
if ([man isMemberOfClass:[Person class]]) {
NSLog(@"man isMemberOfClass: Person");
} else {
NSLog(@"man is't member of Person");
}
if ([obj isMemberOfClass:[NSObject class]]) {
NSLog(@"obj isMemberOfClass: NSObject");
} else {
NSLog(@"obj is't member of NSObject");
}
//类方法
if ([Person isMemberOfClass:[Person class]]) {
NSLog(@"Person isMemberOfClass: Person");
} else {
NSLog(@"Person is't member of Person");
}
if ([Man isMemberOfClass:[Person class]]) {
NSLog(@"Man isMemberOfClass: Person");
} else {
NSLog(@"Man is't member of Person");
}
if ([NSObject isMemberOfClass:[NSObject class]]) {
NSLog(@"NSObject isMemberOfClass: NSObject");
} else {
NSLog(@"NSObject is't member of NSObject");
}
//对象方法
if ([person isKindOfClass:[Person class]]) {
NSLog(@"person isKindOfClass: Person");
} else {
NSLog(@"person is't kind of Person");
}
if ([man isKindOfClass:[Person class]]) {
NSLog(@"man isKindOfClass: Person");
} else {
NSLog(@"man is't kind of Person");
}
if ([obj isKindOfClass:[NSObject class]]) {
NSLog(@"obj isKindOfClass: NSObject");
} else {
NSLog(@"obj is't kind of NSObject");
}
//类方法
if ([Person isKindOfClass:[Person class]]) {
NSLog(@"Person isKindOfClass: Person");
} else {
NSLog(@"Person is't kind of Person");
}
if ([Man isKindOfClass:[Person class]]) {
NSLog(@"Man isKindOfClass: Person");
} else {
NSLog(@"Man is't kind of Person");
}
if ([NSObject isKindOfClass:[NSObject class]]) {
NSLog(@"NSObject isKindOfClass: NSObject");
} else {
NSLog(@"NSObject is't kind of NSObject");
}
}
答案如下:
2020-10-01 21:51:14.241579+0800 ALLWAY-OC[20377:3623321] person isMemberOfClass: Person
person的[self class] 返回 Person == [Person class] 成立
2020-10-01 21:51:14.241655+0800 ALLWAY-OC[20377:3623321] man is't member of Person
man的[self class] 返回 Man == [Person class] 不成立
2020-10-01 21:51:14.241738+0800 ALLWAY-OC[20377:3623321] obj isMemberOfClass: NSObject
obj的[self class] 返回 NSObject == [NSObject class] 成立
2020-10-01 21:51:14.241816+0800 ALLWAY-OC[20377:3623321] Person is't member of Person
Person的ISA是他的元类 所以不成立
2020-10-01 21:51:14.241882+0800 ALLWAY-OC[20377:3623321] Man is't member of Person
Man的ISA是他的元类 所以不成立
2020-10-01 21:51:14.241948+0800 ALLWAY-OC[20377:3623321] NSObject is't member of NSObject
NSObject的ISA是他的元类 所以不成立
2020-10-01 21:51:14.241178+0800 ALLWAY-OC[20377:3623321] person isKindOfClass: Person
person的[self class] 返回 Person == [Person class] 成立
2020-10-01 21:51:14.241265+0800 ALLWAY-OC[20377:3623321] man isKindOfClass: Person
man的[self class] 返回 Man == [Person class] 不成立, 所以循环查找他的父类superClass为Person,所以最终成立
2020-10-01 21:51:14.241343+0800 ALLWAY-OC[20377:3623321] obj isKindOfClass: NSObject
obj的[self class] 返回 NSObject == [NSObject class] 成立
2020-10-01 21:51:14.241436+0800 ALLWAY-OC[20377:3623321] Person is't kind of Person
Person的ISA是他的元类 所以不成立,循环查找他父类NSObject的元类还是不成立
2020-10-01 21:51:14.241494+0800 ALLWAY-OC[20377:3623321] Man is't kind of Person
Man的ISA是他的元类 所以不成立,循环他的父类Person的元类还是不成立,再循环Person的父类NSObject的元类,依旧是不成立的
2020-10-01 21:51:14.241539+0800 ALLWAY-OC[20377:3623321] NSObject isKindOfClass: NSObject
NSObject的ISA是他的元类 所以不成立,所以找NSObject元类的父类为NSObject类,此时tcls == cls成立。
欢迎大家指正!!!
重点是要了解runtime的结构图