你真的明白isKindOfClass 和 isMemberOfClass 的区别么?

前几天看博客发现了一个关于 isKindOfClass 和 isMemberOfClass 的问题,但是感觉分析的不够透彻,所以我在这里试着分析一下,欢迎大家一起讨论。

内容是这样的 (如图1)。

avata

图1

上图中的四个Bool 分别是什么?

我在这里先爆出答案:上面是个Bool 分别是:1 ,0,0,0;

那么问题来了,为毛会是这个结果?

要弄明白这个就要搞清楚isKindOfClass 和 isMemberOfClass 的区别,先来看看官方的说法:

isKindOfClass:Returns a Boolean value that indicates whether the receiver is an instance of given class or an instance of any class that inherits from that class.

isMemberOfClass:Returns a Boolean value that indicates whether the receiver is an instance of a given class.

其实就是这个意思:

isKindOfClass:判断对象是否为某类或其派生类的实例。

isMemberOfClass:判断对象是否为某个特定类的实例。

好,那么先来分析res1 为什么是Yes.

首先了解一下class 方法的实现 (图2)
avata
图2

从图2中可以看出[NSObject class]; 返回的其实还是NSObject,到这里你可能会想

NSObject isKindOfClass NSObject 所以 res1 = Yes。But,But,But,重要的事情说三遍,事实并非如此,接着我们来看一下isKindOfClass 方法的实现(图3)

avata
图3

以及object_getClass 的实现 (图4)
avata

图4

通过查阅objc4 源码 就是上面的图3和图4,会发现object_getClass 返回的是传入的对象的isa,由于我们传入的是类对象,所以isa 指向的是一个元类对象,那么object_getClass((id)self);返回的就是self 的元类对象,那么NSObject 类对象的元类对象是谁呢?如果你了解OC的对象模型的话会知道,NSObject的元类对象为 Meta NSObject Class Object(我们暂且这么叫) 。

回到isKindOfClass 的实现代码里,循环会先获取到NSObject的元类对象即tcls,然后跟NSObject类对象(cls)作比较,此时元类对象不等于类对象,继续循环,找到tcls->superclass,还是得熟悉OC的对象模型,NSObject 元类对象的super 就是NSObject ,没错就是它,此时 tcls 就是 NSObject 类对象,cls 也是NSObject 类对象,所以tcls 等于cls ,此时循环结束,返回Yes。

到这里不知道各位看官是否明白是怎么回事了呢?

下面附上isMemberOfClass 的源码实现 图5
avata

图5

大家可以通过上面isKindOfClass 的分析,以及我提供的源码截图,可以分析一下其他三种res2,res3,res4的结果为什么全是0。

才疏学浅,欢迎大家勘误。多多交流,互相学习!

谢谢您的支持!