1、介绍下runtime的内存模型(isa、对象、类、metaclass、结构体的存储信息等)-问答-阿里云开发者社区-阿里云

开发者社区> 问答> 正文

1、介绍下runtime的内存模型(isa、对象、类、metaclass、结构体的存储信息等)

2020-04-13 15:00:52 4418 1

1、介绍下runtime的内存模型(isa、对象、类、metaclass、结构体的存储信息等)

取消 提交回答
全部回答(1)
  • 游客bnlxddh3fwntw
    2020-04-13 15:03:38

    对象:OC中的对象指向的是一个objc_object指针类型,typedef struct objc_object *id;从它的结构体中可以看出,它包括一个isa指针,指向的是这个对象的类对象,一个对象实例就是通过这个isa找到它自己的Class,而这个Class中存储的就是这个实例的方法列表、属性列表、成员变量列表等相关信息的。

    /// Represents an instance of a class.
    struct objc_object {
        Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
    };
    

    类:在OC中的类是用Class来表示的,实际上它指向的是一个objc_class的指针类型,typedef struct objc_class *Class;对应的结构体如下:

    struct objc_class {
        Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
    
    #if !__OBJC2__
        Class _Nullable super_class                              OBJC2_UNAVAILABLE;
        const char * _Nonnull name                               OBJC2_UNAVAILABLE;
        long version                                             OBJC2_UNAVAILABLE;
        long info                                                OBJC2_UNAVAILABLE;
        long instance_size                                       OBJC2_UNAVAILABLE;
        struct objc_ivar_list * _Nullable ivars                  OBJC2_UNAVAILABLE;
        struct objc_method_list * _Nullable * _Nullable methodLists                    OBJC2_UNAVAILABLE;
        struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE;
        struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE;
    #endif
    
    }
    

    从结构体中定义的变量可知,OC的Class类型包括如下数据(即:元数据metadata):super_class(父类类对象);name(类对象的名称);version、info(版本和相关信息);instance_size(实例内存大小);ivars(实例变量列表);methodLists(方法列表);cache(缓存);protocols(实现的协议列表);

    当然也包括一个isa指针,这说明Class也是一个对象类型,所以我们称之为类对象,这里的isa指向的是元类对象(metaclass),元类中保存了创建类对象(Class)的类方法的全部信息。

    以下图中可以清楚的了解到OC对象、类、元类之间的关系

    image.png

    从图中可知,最终的基类(NSObject)的元类对象isa指向的是自己本身,从而形成一个闭环。

    元类(Meta Class):是一个类对象的类,即:Class的类,这里保存了类方法等相关信息。

    我们再看一下类对象中存储的方法、属性、成员变量等信息的结构体

    objc_ivar_list:存储了类的成员变量,可以通过object_getIvar或class_copyIvarList获取;另外这两个方法是用来获取类的属性列表的class_getProperty和class_copyPropertyList,属性和成员变量是有区别的。

    struct objc_ivar {
        char * _Nullable ivar_name                               OBJC2_UNAVAILABLE;
        char * _Nullable ivar_type                               OBJC2_UNAVAILABLE;
        int ivar_offset                                          OBJC2_UNAVAILABLE;
    #ifdef __LP64__
        int space                                                OBJC2_UNAVAILABLE;
    #endif
    }                                                            OBJC2_UNAVAILABLE;
    
    struct objc_ivar_list {
        int ivar_count                                           OBJC2_UNAVAILABLE;
    #ifdef __LP64__
        int space                                                OBJC2_UNAVAILABLE;
    #endif
        /* variable length structure */
        struct objc_ivar ivar_list[1]                            OBJC2_UNAVAILABLE;
    } 
    
    

    objc_method_list:存储了类的方法列表,可以通过class_copyMethodList获取。

    结构体如下:

    struct objc_method {
        SEL _Nonnull method_name                                 OBJC2_UNAVAILABLE;
        char * _Nullable method_types                            OBJC2_UNAVAILABLE;
        IMP _Nonnull method_imp                                  OBJC2_UNAVAILABLE;
    }                                                            OBJC2_UNAVAILABLE;
    
    struct objc_method_list {
        struct objc_method_list * _Nullable obsolete             OBJC2_UNAVAILABLE;
    
        int method_count                                         OBJC2_UNAVAILABLE;
    #ifdef __LP64__
        int space                                                OBJC2_UNAVAILABLE;
    #endif
        /* variable length structure */
        struct objc_method method_list[1]                        OBJC2_UNAVAILABLE;
    } 
    

    objc_protocol_list:储存了类的协议列表,可以通过class_copyProtocolList获取。

    结构体如下:

    struct objc_protocol_list {
        struct objc_protocol_list * _Nullable next;
        long count;
        __unsafe_unretained Protocol * _Nullable list[1];
    };
    
    0 0
相关问答

0

回答

大佬们,这个cdc采集Oracle的数据,为啥number类型采过来就变成了对象?

2022-07-13 17:23:14 56浏览量 回答数 0

1

回答

flink 1.14为什么在flink run提交参数里加上-ynm参数不生效呢?

2022-06-09 20:36:08 129浏览量 回答数 1

1

回答

Lxc为什么可以大大加快container的启动过程呢?

2022-04-02 16:53:22 226浏览量 回答数 1

0

回答

java.lang.RuntimeException: Unable to insta报错怎么办?

2021-10-25 18:43:55 158浏览量 回答数 0

1

回答

@JFinal controller setAttr 一个树状结构的数据对象到页面?报错

2020-06-22 22:34:54 281浏览量 回答数 1

1

回答

入 Go 必读:大型Go工程的项目结构及实战思考!

2020-01-09 17:15:18 2409浏览量 回答数 1

1

回答

获取完整的当前crontab行,并为每行创建唯一的结果电子邮件标头(来自,主题等)

2020-01-05 19:08:39 273浏览量 回答数 1

1

回答

深圳大学考研 考906 数据结构与算法 推荐什么书啊

2018-07-17 15:28:21 1181浏览量 回答数 1

5

回答

7月4号 ECS 装的LNMP,内存持续高涨,求助

2016-08-06 16:12:57 4020浏览量 回答数 5

3

回答

我不懂技术,我们公司要放大量图片在阿里云的对象存储 OSS上面,我要先怎么做?

2016-02-18 15:56:13 3428浏览量 回答数 3
0
文章
574
问答
问答排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载