iOS之isKindOfClas、isMemberOfClass
2020-07-12 本文已影响0人
枫叶无处漂泊
首先我们先来看一段代码:
@interface Person : NSObject
@end
@implementation Person
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSLog(@"%@", [NSObject class]);
NSLog(@"%@", [Person class]);
BOOL res1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
BOOL res2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
BOOL res3 = [(id)[Sark class] isKindOfClass:[Sark class]];
BOOL res4 = [(id)[Sark class] isMemberOfClass:[Sark class]];
NSLog(@"%d--%d--%d--%d", res1, res2, res3, res4);
}
return 0;
}
输入结果:
NSObject
Person
1-0-0-0
可能执行结果出乎大多数人的意料,
如果不是很清楚对象、类对象、元类关系的,可以先看一下下图:
对象、类对象、元类关系.png
- 对象的isa指针指向类对象
- 类对象的指针指向元类
//类对象返回自身
+ (Class)class {
return self;
}
[NSObject class]、[Person class]返回还是当前类对象
下面可以看看两个isMemberOfClass、isKindOfClass内部实现,
//isMemberOfClass实现
- (BOOL)isMemberOfClass:(Class)cls {
return [self class] == cls;
}
isMemberOfClass比较两个isa指向的类对象是否一样。
能判断对象是否是当前类的实例对象.
//isKindOfClass实现
- (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
前者对象的(class)类对象是否与后者类对象相同,如果相同返回YES
不相等的话就,就继续对象的类对象的superclass看是否相等,一直找到根类
一、 [(id)[NSObject class] isKindOfClass:[NSObject class]];
其实通过isKindOfClass内部实现源码,可以理解为:
- 前者[[NSObject class] class](NSObject的Meta Class)与后者[NSObject class](NSObject的class)是否相等
- 相等返回true
- 不相等的话,就遍历NSObject的元类的superclass,看是否相等.
- 如上图NSObject的元类的superclass指向NSObject的类对象,所以返回的true。
二、[(id)[NSObject class] isMemberOfClass:[NSObject class]]
- isMemberOfClass只能判断对象是否是当前类的实例对象,NSObject的元类肯定不是NSObject类对象的实例。所以返回false。
三、[(id)[Person class] isKindOfClass:[Sark class]];
执行流程大概是这样:
- [[Person class]class] 执行完之后调用 isKindOfClass,
- 第一次 for 循环,Person 的 Meta Class 与 [Person class] 不等,
- 第二次 for 循环,Person Meta Class 的 super class 指向的是 NSObject Meta Class, 和 Person Class 不相等。
- 第三次 for 循环,NSObject Meta Class 的 super class 指向的是 NSObject Class,和 Person Class 不相等。
- 第四次循环,NSObject Class 的super class 指向 nil, 和 Person Class 不相等。第四次循环之后,退出循环,所以第三行的 res3 输出为 NO。
四、[(id)[Sark class] isMemberOfClass:[Sark class]]
isa 指向 Person 的 Meta Class,和 Person Class 也不等。