美文网首页
类的原理(中)

类的原理(中)

作者: KG丿夏沫 | 来源:发表于2021-07-02 13:30 被阅读0次

上一篇类的原理(上)中我们探索了类的属性以及对象方法的存储位置,但是我们在探索过程中并没有找到成员变量和类方法的存储位置,那么这篇文章我们一起探索下成员变量和类方法的存储位置。

成员变量

1、我们通过上篇分析后没有找到成员以及类方法的存储位置,所以我们继续到class_rw_t结构体去分析,最后找到如下函数:

image.png

2、那么我们再去使用源码+lldb去调式一下看看,这个里面存储的是什么呢?

image.png

3、从上图打印结果我们可以看到,在class_rw_t结构体中的ro()方法回调能够得到一个class_ro_t结构体,这个结构体的内容比较多,但是经过简化我们需要的后,大概如下:

struct class_ro_t {
    uint32_t flags;
    uint32_t instanceStart;
    uint32_t instanceSize;
#ifdef __LP64__
    uint32_t reserved;
#endif

    union {
        const uint8_t * ivarLayout;
        Class nonMetaclass;
    };

    void *baseMethodList;
    protocol_list_t * baseProtocols;
    const ivar_list_t * ivars;

    const uint8_t * weakIvarLayout;
    property_list_t *baseProperties;
}

以上就是我们需要的一些基本的成员,能够得到我们想要的成员变量列表、方法列表,协议列表,属性列表等等。

4、到这里我们找到了成员变了存储的位置,也额外找到一些类的其它结构存储位置。然后我们看到了一个baseMethodList,顺带看看这个?经过lldb打印结果如下:

image.png

从以上看出还是只是对象方法,并没有我们的类方法,然后我们继续去探索类方法的存储位置。

类方法

1、目前我们已经找到了类的属性、成员变量、对象方法的存储位置,这一节我们探索类方法的存储位置,我们在类中找过了所有与方法有关系的函数,都没有找到类方法的存储位置,那么我们是否有这么一个猜测,它是否在元类中?因为到目前为止,没有想到元类有什么作用。所以带着好奇心我们去看下元类中的bits

2、首先我们通过lldb去看下bits中的methods()包含啥?但是我们怎么访问到元类呢?很简单之前对象的本质这篇文章中有介绍isa_t这个联合体的时候介绍了一个掩码,那么我们通过这个掩码就可以得到元类,看下面结果:

image.png

3、从上图我们可以看到,类方法确实存储在了元类中。这个过程中我们不是拿的KGPerson.class的地址,而是通过isa取模然后地址偏移最后得到的元类,其它的都是和读取类的操作是一样的。

4、那么到此我们经过两篇文章的探索,大概分析了类的属性、成员变量、对象方法(实例方法)、类方法的存储位置。

总结

经过两篇文章的分析,我们探究了类的属性、成员变量、类方法、对象方法的存储位置,大概了解了一些类的内存结构。

相关文章

网友评论

      本文标题:类的原理(中)

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