类的原理(中)

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

成员变量

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

总结

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

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

推荐阅读更多精彩内容

  • 对于一个iOS开发者来说对象是最熟悉不过的,因为我们开发的时候时刻都是在操作各种对象,而且都知道对象是通过了类的初...
    KG丿夏沫阅读 149评论 0 0
  • iOS OC底层探索 iOS Objective -C alloc 调用流程[https://juejin.im/...
    just东东阅读 1,183评论 2 2
  • 类方法的归属问题 我们在iOS原理探索04--类结构的分析中知道 类的实例方法和类的属性都存在bits中,我们发现...
    HardCabbage阅读 486评论 1 1
  • 类的结构和定义 首先跟踪源码,找到Class的的定义,发现其本质为objc_class类型的指针,并且 objc_...
    尘舒阅读 674评论 2 5
  • 前言 上一片我们用LLDB和源码探索类的底层实现,这篇文章主要补充一下上一篇以及一些问题,这里先留几个问题。 1、...
    Nulll阅读 311评论 0 1