美文网首页
你真的明白isKindOfClass 和 isMemberOf

你真的明白isKindOfClass 和 isMemberOf

作者: 潭清 | 来源:发表于2018-05-31 23:50 被阅读15次

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

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

     图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)

    图2

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

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

    图3

    以及object_getClass 的实现 (图4)

    图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

    图5

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

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

    相关文章

      网友评论

          本文标题:你真的明白isKindOfClass 和 isMemberOf

          本文链接:https://www.haomeiwen.com/subject/hcncsftx.html