以前用到这两个函数的时候,总是会分不清这两个函数的作用,记了笔记也经常翻出来看,这次就来彻底了解一下
以前的笔记
先看一下isKindOfClass
作用都清楚了,我们直接去objc的源码项目里去看,先看isKindOfClass
实例方法是查找对象所属的类,然后比较,不相等就再找父类,直到NSObject(因为NSObject的superclass = nil)。 类方法是查找类的ISA指针,实力的ISA指针指向类,类的ISA指针指向元类。元类的父类最后会找到NSObject上。
关于ISA的走势图,大家应该都熟悉这张图,这里就不再多说了。
所以关于isKindOfClass的实现原理差不多就是这样
再看看isMemberOfClass
也分实例方法和类方法。 实例方法是把自身所属的类和传入的类作比较,静态方法是把自身的ISA指针和传入的类做比较。
通过这四个函数的实现,也符合了之前笔记的总结。
看一下一个面试题
BOOL res1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
BOOL res2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
BOOL res3 = [(id)[TestObject class] isKindOfClass:[TestObject class]];
BOOL res4 = [(id)[TestObject class] isMemberOfClass:[TestObject class]];
他们的结果是多少?
这些都是类方法的isKindOfClass和isMemberOfClass比较。NSObject的ISA会指向元类NSObject,元类NSObject的superClass又指向NSObject自己。TestObject的ISA指向TestObject元类,TestObject元类的superClass最后又会指向NSObject根元类,再指向NSObject。
所以上面的结果除了第一个是YES,剩下的都是NO。