彻底区分isKindOfClass和isMemberOfClass

347 阅读1分钟

以前用到这两个函数的时候,总是会分不清这两个函数的作用,记了笔记也经常翻出来看,这次就来彻底了解一下

以前的笔记

先看一下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。