isKindOfClass()方法

由下方代码可知,isKindOfClass()确定一个对象是否是这个类的成员,或者有派生类,isMemberOfClass()只能确定对象是否是当前类的成员

re1和re3是判断当前类的指针是否指向它自己

re2和re4是判断当前类是否是它自己


01

congoing打印结果可以看出,

02

直接源码查找isKindOfClass()方法发现

+isKindOfClass()方法中

        Class tcls=self—>ISA(),获取当前类的元类,那么tcls就是当前类的元类

        tcls=tcls—>getSuperclass(),获取元类的父类。

-isKindOfClass()方法中

    [self  class] == cls;当前类是否是元类

+isMemberOrClass()方法中

        self->ISA() == cls,元类是否等于当前类

由此可知,对于NSObject和LGPerson来说元类不是当前类,因此re2和re3都返回0

03

但是有个问题,在isKindOfClass()两个方法中加断点,发现并没有走这两个函数

接下来打开汇编发现,并没找到isKindOfClass(),但是找到了objc_opt_isKindOfClass()方法

04

在源码中搜索objc_opt_isKindOfClass(),可以的到这个函数,打上断点,发现程序运行时都走这里的。

然而不同的是re1在这个for循环中走了两次,re3在这个循环中走了三次。结合图05的代码调试re1的过程可知,re1第一次走tcls只获取到地址,第二次才获取到NSObject。re3前两次也是只获取到地址,第三次才获取到NSObject。(只获取到地址,是因为找到了元类)

同理re5和re7在这个for循环中都只走了一次,是因为获取到当前类,tcls是有值的,所以直接跳出循环。所以re5和re7返回1。

        re1和re3过程可以理解为:

             对于NSObject来说,是NSObject—>NSObject根元类—>根元类父类,

            NSObject根元类父类还是NSObject,因此re1返回1

            对于LGPerson来说,是LGPerson—>LGPerson元类—>LGPerson根元类—>根元类父类,

            LGPerson的根元类的父类是NSObject,因此re3返回0


05

-isMemberOrClass()方法中

- (BOOL)isMemberOfClass:(Class)cls {    return [self class] == cls;}


re6和re8在代码运行过程中是走了这里,由此可知,对于NSObject和LGPerson来说对象指向的类是当前类,因此re6和re8都返回1


疑问:

在运行lgKindofDemo()之前,p走了三遍-isKindOfClass()方法,最终return no。

又定义了一个NSObject *n = [[NSObject alloc] init];,n是走了两遍-isKindOfClass()方法,最终return no

实例化之后,调用该对象为什么要走-isKindOfClass()这个方法,另外+isKindOfClass()方法在什么情况下使用

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容