面试题: isKindOfClass & isMemberOfC
先复习isa走位和继承流程图
isa流程图.png
BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]]; //1
BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]]; //0
BOOL re3 = [(id)[LGPerson class] isKindOfClass:[LGPerson class]]; //0
BOOL re4 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]]; //0
NSLog(@" re1 :%hhd\n re2 :%hhd\n re3 :%hhd\n re4 :%hhd\n",re1,re2,re3,re4);
BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]]; //1
BOOL re6 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]]; //1
BOOL re7 = [(id)[LGPerson alloc] isKindOfClass:[LGPerson class]]; //1
BOOL re8 = [(id)[LGPerson alloc] isMemberOfClass:[LGPerson class]]; //1
NSLog(@" re5 :%hhd\n re6 :%hhd\n re7 :%hhd\n re8 :%hhd\n",re5,re6,re7,re8);
在前四题中是调用的类方法
+isKindOfClass-
+isMemberOfClass
先看下这两种类方法的底层实现:
isKindOfClass
+ (BOOL)isKindOfClass:(Class)cls {
// 获取类的元类 vs 传入类
// 根元类 vs 传入类
// 根类 vs 传入类
for (Class tcls = self->ISA(); tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
第一题:
BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]]; //1
解析
类(NSObject)的元类(元类NSObject) 是否等于类(NSObject) ?
显然不等, 然后 tcls赋值为tcls的父类(元类NSObject的父类为NSObject), isKindOfClass传入的参数 cls (NSObject) == 此时的tcls(NSObject)
所以返回YES
图片.png
第三题
BOOL re3 = [(id)[LGPerson class] isKindOfClass:[LGPerson class]]; //0
解析
1.类(LGPerson)的元类(元类LGPerson) 是否等于类(LGPerson) ? 不等
2.元类(元类LGPerson) 的父类(元类NSObject)是否登录类(LGPerson) ? 不等
3.元类NSObject)的父类(根源类(NSObject))是否等于类(LGPerson) ? 不等
4.根源类(NSObject)的父类(NSObject)是否登录类(LGPerson) ? 不等
5.NSObject的父类(nil)是否登录类(LGPerson) ? 不等
返回nil
isMemberOfClass
+ (BOOL)isMemberOfClass:(Class)cls {
//元类 vs 类
return self->ISA() == cls;
}
第二题 :
BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]]; //0
解析
类的元类 ==类?
元类(元类NSObject) ==类(NSObject) ?
显然不等 返回NO
图片.png
第四题 :
BOOL re4 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]]; //0
解析
1.类LGPerson 的元类(元类LGPerson) 是否等于类(LGPerson) ? 不等
在后四题中是调用的类方法
-isKindOfClass-
-isMemberOfClass
先看下这两种类方法的底层实现:
-isKindOfClass
- (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
第五题
BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]]; //1
解析
1.类(NSObject)的 class (NSObject) 是否等于 类(NSObject) ? 相等
返回YES
第七题
BOOL re7 = [(id)[LGPerson alloc] isKindOfClass:[LGPerson class]]; //1
解析
1.类(LGPerson)的 class (LGPerson) 是否等于 类(LGPerson) ? 相等
返回YES
-isMemberOfClass
- (BOOL)isMemberOfClass:(Class)cls {
return [self class] == cls;
}
第六题
BOOL re6 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]]; //1
解析
1.类(NSObject)的 class (NSObject) 是否等于 类(NSObject) ? 相等
返回YES
第八题
BOOL re8 = [(id)[LGPerson alloc] isMemberOfClass:[LGPerson class]]; //1
解析
1.类(LGPerson)的 class (LGPerson) 是否等于 类(LGPerson) ? 相等
返回YES
源码分析总结
isKindOfClass
类方法:元类 --> 根元类 --> 根类 -->nil与 传入类的对比
实例方法:对象的类 --> 父类 --> 根类 --> nil 与 传入类的对比
isMemberOfClass
类方法: 类的元类 与 传入类 对比
实例方法:对象的父类 与 传入类 对比