美文网首页
iOS运行时中isa指针的本质

iOS运行时中isa指针的本质

作者: MiniCoder | 来源:发表于2020-03-08 21:11 被阅读0次

    在OC中,因为类也是一个对象,所以也必须是另外一个类的实例,这个类就是元类(metaclass)。元类保存了类方法的列表。当一个类方法被调用的时候,元类会首先查找他本身是否有该方法的实现,如果没有,则元类会向他的父类查找方法,这样就可以一直找到继承链的头。
    元类也是一个对象,元类的isa指针又指向哪里呢?为了设计的完整性,所有的元类的isa指针都会指向一个根元类。根元类的isa指针又会指向他自己,这样就形成了一个闭环


    1981114-5036d6de4e94ce44.png

    Class是一个指向objc_class(类)结构体的指针,而id是一个指向objc_object(对象)结构体的指针。
    objc_object(对象)中isa指针指向的类结构称为objc_class(该对象的类),objc_class存放着普通成员变量与对象方法 (“-”开头的方法)。
    objc_class(类)中isa指针指向的类结构称为metaclass(该类的元类),其中存放着static类型的成员变量与static类型的方法 (“+”开头的方法)。

    从这里可以知道,OC的类其实也是一个对象,一个对象就要有一个它属于的类,意味着类也要有一个 isa 指针,指向他所属的类。那么元类的类是什么?就是我们所说的元类 (MetaClass) ,所以,元类就是类所属的类。从消息机制的层面来说:

    当你给对象发送消息时,消息是在寻找这个对象的类的方法列表 。
    当你给类发消息时,消息是在寻找这个类的元类的方法列表。
    下面通过代码我们可以看一下详细的指向过程

       Person *p = [Person new];
        Class cls = object_getClass(p);
        //metaClass
        Class metaCls1 = object_getClass(cls);
        Class metaCls2 = object_getClass(metaCls1);
        Class metaCls3 = object_getClass(metaCls2);
        Class metaCls4 = object_getClass(metaCls3);
        Class class =  metaCls4;
        NSLog(@"实例 = %p ,类对象 =  %p,元类=  %p,根元类=  %p,根元类=  %p",p,cls,metaCls1,metaCls2,metaCls3);
    
    
    实例 = 0x6000001a2440 ,类对象 =  0x107541bb8,元类=  0x107541be0,根元类=  0x7fff89e06698,根元类=  0x7fff89e06698
    

    我们可以在类中找到实例对象的方法,也就是我们,在元类中找到类对象方法,也就是我们用到的+号方法。

    相关文章

      网友评论

          本文标题:iOS运行时中isa指针的本质

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