经典面试题isKindOfClass与isMemberOfClass的理解
//-----使用 iskindOfClass & isMemberOfClass 类方法
BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
BOOL re3 = [(id)[Person class] isKindOfClass:[Person class]];
BOOL re4 = [(id)[Person class] isMemberOfClass:[Person class]];
//------iskindOfClass & isMemberOfClass 实例方法
BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];
BOOL re6 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];
BOOL re7 = [(id)[Person alloc] isKindOfClass:[Person class]];
BOOL re8 = [(id)[Person alloc] isMemberOfClass:[Person class]];
isKindOfClass 源码解析
类方法
+ (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = self->ISA(); tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
self
指的是类
,由于类的isa
指向元类,所以self->ISA()
代表当前类的元类,元类继承于根元类,根元类继承于根类
- 获取当前类的
元类
与传入类
比较,如果相同返回true
,否则继续 - 获取当前类的
根元类
与传入类
比较,如果相同返回true
,否则继续 - 获取当前的
根类
与传入类
比较,如果相同返回true
,否则返回false
-
[(id)[NSObject class] isKindOfClass:[NSObject class]]
=true
第一次循环比较:NSObject 的元类既根元类
与根类
比较,返回false
第二次根元类
的父类既根类
与根类
比较,返回true
-
[(id)[Person class] isKindOfClass:[Person class]];
=false
第一次循环比较:Person 的元类
与Person类
比较,返回false
第二次Person 的元类的父类
既根元类
与Person类
比较,返回false
第三次根元类
的父类既根类
与Person类
比较,返回false
第四次根类
的父类既nil
与Person类
比较,返回false
实例方法
- (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
- 获取当前对象的
类
与传入类
比较,如果相同返回true
,否则继续 - 获取当前对象的
父类
与传入类
比较,如果相同返回true
,否则继续 - 获取当前对象的
根类
与传入类
比较,如果相同返回true
,否则继续3.
nil与
传入类比较,如果相同返回
true,否则返回
false `
-
[(id)[NSObject alloc] isKindOfClass:[NSObject class]];
根类
与根类
比较。返回true
-
[(id)[Person alloc] isKindOfClass:[Person class]];
Person类
与Person类
比较,返回true
isMemberOfClass源码解析
类方法:获取类的元类,与 传入类对比
+ (BOOL)isMemberOfClass:(Class)cls {
return self->ISA() == cls;
}
-
[(id)[NSObject class] isMemberOfClass:[NSObject class]];
根元类
与根类
比较,返回false
-
[(id)[Person class] isMemberOfClass:[Person class]];
元类
与Person 类
比较,返回false
实例方法: 获取对象的类,与 传入类对比
- (BOOL)isMemberOfClass:(Class)cls {
return [self class] == cls;
}
-
[(id)[NSObject alloc] isMemberOfClass:[NSObject class]];
根类
与根类
比较,返回true
-
[(id)[Person alloc] isMemberOfClass:[Person class]];
Person 类
与Person 类
比较,返回true
总结
根据isa走势图
+号方法 用当前类的->isa
,与传入类比较
-号方法 用当前类的class
,与传入类比较
isKindOfClass
从下往上找,类走红,对象走蓝
isMemberOfClass
类找元类,对象找类
网友评论