美文网首页
isMemberOfClass和isKindOfClass底层分

isMemberOfClass和isKindOfClass底层分

作者: 嘿_原来你也在这里 | 来源:发表于2021-07-18 22:57 被阅读0次

    为了方便讲解,以下列出isMemberOfClass和isKindOfClass的实例方法和类方法底层实现

    底层源码

    由上图可知:

    isMemberOfClass:

    此处YYPerson继承至NSObject

    isMemberOfClass 打印结果

    分析:

    实例方法:因为只是简单的判断方法调用者的类对象是否等于传入的cls,所以[p1 isMemberOfClass:[NSObject class]] 为0[p1 isMemberOfClass:[YYPerson class]]为1

    类方法:是通过判断object_getClass((id) self ) == cls,我们可知类方法中的self是类对象,所以是判断元对象是否等于cls,很显然YYPerson元对象不是NSObject类对象,也不等于YYPerson类对象,所以[YYPerson isMemberOfClass:[NSObject class]]为0,[YYPerson isMemberOfClass:[YYPerson class]]为0。

    补充:

    object_getClass(id obj):此方法如果传入的是instance对象,返回class对象。如果是class对象,返回mate-class对象。如果是meta-class对象,返回NSObject的meta-class对象

    objc_getClass(const char *) :传入字符串类名,返回对应类对象

    -(Class)class; + (Class) class; : 返回的是类对象

    isKindOfClass:

    isKindOfClass 打印结果

    分析:

    实例方法:实例方法中[self class],返回类对象,即tcls为类对象,首先会判断tcls是否等于cls,如果不等于将继续遍历,tcls supperClass指针继续往上查找。

    [p1 isKindOfClass:[NSObject class]]:

    因为tcls 为p1类对象,因为不等于[NSObject class],所以继续遍历(supperClass指针指向可以查看OC对象内存布局这一节),找到[NSObject class],此时相等所以打印1;

    [p1 isKindOfClass:[YYPerson class]]:

    因为tcls 为p1类对象,等于[YYPerson class]所以打印1;

    类方法:类方法中object_getClass((id) self ),返回meta对象,即tcls为meta对象,首先会判断tcls是否等于cls,如果不等于将继续遍历,tcls supperClass指针继续往上查找。

    [YYPerson isKindOfClass:[NSObject class]]:

    因为tcls 为p1元对象,因为不等于[NSObject class],所以继续遍历(supperClass指针指向可以查看OC对象内存布局这一节),找到NSObject 元对象,此时仍然不相等,所以继续遍历,由于Root  Class(meta)的supperClass指针指向,Root Class(class),(可查看OC对象内存布局指针指向图,或者注意点说明) 所以NSObject 元对象的supperClass 最终指向NSObject类对象,所以相等,打印1

    [YYPerson isKindOfClass:[YYPerson class]]:

    因为tcls 为p1元对象,因为不等于YYPerson 类对象,所以继续遍历找到NSObject 元对象,此时仍然不相等,所以继续遍历,找到NSObject类对象仍然不相等,继续遍历,因为NSObject的类对象supperClass指针为nil,所以不相等,打印0;

    总结

    isKindOfClass和isMemberOfClass:

    两者都能检测一个对象是否是某个类的成员, 两者之间的区别是:isKindOfClass不但可以用来确定一个对象是否是一个类的成员,也可以用来确定一个对象是否是派生自该类的类的成员 ,而isMemberOfClass做不到后一点。

    实例方法都是判断对象的类对象是否==传入参数,类方式都是判断元对象是否== 传入参数。

    但是isKindOfClass当判断不等于时,还会去查找superClass指针指向的对象是否等于传入参数。而isMemberOfClass不会。因此isKindOfClass可以确定一个对象是否是一个类的成员,也可以用来确定一个对象是否是派生自该类的类的成员。

    相关文章

      网友评论

          本文标题:isMemberOfClass和isKindOfClass底层分

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