美文网首页iOS专家之路
iOS runtime 内存模型

iOS runtime 内存模型

作者: 落夏简叶 | 来源:发表于2020-03-25 17:23 被阅读0次

    源码下载地址:https://opensource.apple.com/tarballs/objc4/,我下载了当前最新的objc4-779.1.tar.gz

    注:iPhone 程序和 Mac OS X v10.5 及以后的系统中的 64 位程序使用的都是 Objective-C 运行时系统的objc 2.0版本。源码中有大量宏条件, 注意查看条件。如#if !__OBJC2__, 此条件下的代码是无效的,网上流传的许多以前的资料是过时的,有助于理解,但注意区分。

    对象

    OC是一门面向对象的语言,一切皆对象。OC中定义的对象是struct objc_object,被定义在了objc-private.h文件中。

    struct objc_object {
    private:
      isa_t isa;
    
    public:
      Class ISA();
      Class rawISA();
      Class getIsa();
      
      uintptr_t isaBits() const;
    
      void initIsa(Class cls /*nonpointer=false*/);
      void initClassIsa(Class cls /*nonpointer=maybe*/);
      void initProtocolIsa(Class cls /*nonpointer=maybe*/);
      void initInstanceIsa(Class cls, bool hasCxxDtor);
    
      Class changeIsa(Class newCls);
    ....
    }
    

    这里面有一个最重要的私有变量isa,它是一个指针,指向的是什么,用一个清晰明了的图来看一下(superclass看下段中类的源码就明白了)。

    网上最有名的解释isa、superclass指向的图
    yy大神画的这个图我觉得更清晰明了,本来自己想画的就是这种

    注:根元类一般是NSObject, 还有一个NSProxy,这里假定Cat继承自NSObject,如果继承自NSProxy,图中的NSObject换成NSProxy即可。

    此文件中也能找到id的定义,typedef struct objc_object *id;。那么也就能理解为什么id能指向任何对象了。

    类其实也是一个对象,被定义为struct objc_class,在objc-runtime-new.h文件中,继承自objc_object

    struct objc_class : objc_object {
        // Class ISA;
        Class superclass;
        cache_t cache;             // formerly cache pointer and vtable
        class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags
    
        class_rw_t *data() const {
            return bits.data();
        }
        void setData(class_rw_t *newData) {
            bits.setData(newData);
        }
    
        void setInfo(uint32_t set) {
            ASSERT(isFuture()  ||  isRealized());
            data()->setFlags(set);
        }
    ....
    }
    

    cache_t cache cache 是为了方法调用性能优化,将调用过的方法缓存,当对某个对象发送消息时先从cache中找,找不到再到isa指向的类中寻找方法实现。提高效率。
    class_data_bits_t内容很少,重点在包装的bits.data().
    class_rw_tbits.data()返回的类型。class_rw_t可以动态修改。可以动态添加方法、属性到methods,properties,properties中。class_rw_t 包含class_ro_t

    struct class_rw_t {
        // Be warned that Symbolication knows the layout of this structure.
        uint32_t flags;
        uint16_t version;
        uint16_t witness;
    
        const class_ro_t *ro;
    
        method_array_t methods;
        property_array_t properties;
        protocol_array_t protocols;
    
        ...
    

    class_ro_t存储的大多是类在编译时就已经确定的信息。

    struct class_ro_t {
        uint32_t flags;
        uint32_t instanceStart;
        uint32_t instanceSize;
    #ifdef __LP64__
        uint32_t reserved;
    #endif
    
        const uint8_t * ivarLayout;
        
        const char * name;
        method_list_t * baseMethodList;
        protocol_list_t * baseProtocols;
        const ivar_list_t * ivars;
    
        const uint8_t * weakIvarLayout;
        property_list_t *baseProperties;
    ...
    }
    
    元类

    类也是对象,是某个类的实例。这个“某个类”被称为元类。

    • 类的isa指针指向其元类
    • 元类也是某个类的实例,这个“某个类”被称为根元类。
    • 元类的isa指针指向根元类,根元类的isa指针指向自己
    • 类方法保存在元类中

    参考:

    1. 证明isa指向关系,以及簇类
      https://blog.csdn.net/u013480070/article/details/100155929
    2. 对象的方法存在类中,类方法存在元类中
      https://juejin.im/post/5ac649b6518825558a06da89
    3. 雷纯锋Objective-C 对象模型
    4. YY大神的 Objective-C 中的类和对象
    5. 玉令天下Objective-C Runtime

    相关文章

      网友评论

        本文标题:iOS runtime 内存模型

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