类的结构浅析

220 阅读2分钟

类的结构浅析

类是什么?类是怎么样的一个结构?

在日常开发中,我们接触到的最多的就是对象的初始化以及创建一个个我们需要的类,前面我们总结了对象的初始化流程,isa的相关知识,今天我们来总结下类的结构。

类的本质

其实类的本质是个结构体对象,em....一句话结束了~

好吧,太儿戏了,稍微说几句好啦~

首先通过 Class Test = object_getClass(t); 我们试着jump to Definition,去查看Class的结构, em....貌似看不了,所以只能编译成c++的代码,clang -rewrite-objc main.m -o main.cpp,然后你会发现还是没办法jump to Definition,没办法我们就只能搜索Class相关的词,

在第一行我们可以看到 objc_class 结构体类型申明,看着应该和Class有点联系,然后当前搜索obcj_class, 然后发现 typedef struct objc_class *Class; 这下明白了,Class是个objc_class类型的结构体,接下来我们去看看objc_class是什么?

如图是objc_class结构体的定义,继承自objc_object,

/// Represents an instance of a class.

struct objc_object {

Class _Nonnull isa  OBJC_ISA_AVAILABILITY;

};

也就是可以理解其实我们接触的所有对象,类都是继承自于objc_object,编译成OC语言即NSObject,

@interface NSObject <NSObject> {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-interface-ivars"
    Class isa  OBJC_ISA_AVAILABILITY;
#pragma clang diagnostic pop

}

那么类的本质其实就是一个结构体对象。

类的结构

我们知道类其实是个objc_class的结构体对象,接下来我们分析下平时我们开发中定义的属性、方法都是存储在哪? 通过上图可以猜测应该是存储在 class_data_bits_t bits,顺着源代码查找发现struct class_ro_t,看着结构定义,应该是我们要找的东西,em...代码验证下。

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;

//...
}

如图我们对Test类的内存地址进行偏移32位得到class_data_bits_t bits的内存地址,然后通过系统的函数方法变量获取我们想要的结果,这时候是不是看到比较熟悉的字眼,ivars,baseMethodList,baseProperties等等,baseMethodList只存储Test类对象的实例方法,而类方法是存在Test类元类的baseMethodList里,这点要知道。

以上我们大概了解了类的本质以及类的结构、变量属性方法等存储的位置,em....差不多就到这吧。

PS:欢迎留言探讨交流,目的纯粹为了学习进步。