返回

OC底层原理,结构体来分析!

IOS

OC 底层结构体的奥秘:揭开 Objective-C 内核世界的面纱

在 Objective-C 的世界里,对象是至高无上的存在,而对象的本质,正是结构体。了解这些结构体的奥秘,就如同拥有了开启 Objective-C 底层编程魅力的钥匙。踏上我们的探索之旅,揭开 OC 底层结构体的面纱!

OC 对象:一切皆结构体

每一件 OC 对象,都指向一个 objc_object 结构体。这个结构体可谓是对象的基石,包含了该对象的根本信息:

struct objc_object {
    Class isa;
};

其中的 isa 指针,直指对象的类结构体 (objc_class)。类结构体就好比对象的户口本,记录了对象的归属、特征和能力。

类结构体:对象的元数据宝库

objc_class 结构体,承载着类的元数据信息,宛如一个全面的档案库:

struct objc_class {
    Class isa;
    const char *name;
    Class superclass;
    const char **protocols;
    const char *ivar_layout;
    MethodList *methodLists;
    Class *subclass_list;
    cache_t cache;
    IMP *vtable;
};
  • isa 指针:指向类的元类结构体,元类也是一种类,负责管理类的行为。
  • name:类的名字,一目了然。
  • superclass:指向父类的结构体,追溯家族传承。
  • protocols:指向类遵循的协议列表,规范了类的行为准则。
  • ivar_layout:了类的实例变量布局,刻画了对象内部的格局。
  • methodLists:一个方法列表,收纳了类中所有方法的实现,堪称类的能力大全。
  • subclass_list:列出了类的所有子类,展示了类的繁衍生息。
  • cache:一个缓存,存储着类的元数据信息,方便快速检索。
  • vtable:一个虚函数表,记录了虚方法的实现地址,为动态方法调用铺平了道路。

实例变量布局:窥探对象内部

ivar_layout 是类结构体中的一块宝地,它揭示了类的实例变量布局。每个变量信息都包括:

  • 编码前缀:揭示变量类型的字母符号,如 @ 表示对象指针。
  • 偏移量:十进制整数,展示变量在对象结构体中的位置。
  • 变量名称:一个字符串,直指变量的本名。

方法列表:类能力的集合

MethodList 是类结构体中的一份方法清单,它收录了类中所有方法的实现:

struct Method {
    SEL name;
    const char *types;
    IMP imp;
};
  • name:方法的选择器,是一个独特的字符串标识符。
  • types:方法的参数类型和返回值类型的字符串,勾勒出方法的输入输出关系。
  • imp:指向方法实现的地址,指引执行的道路。

虚函数表:动态方法调用的桥梁

vtable 是类结构体中的另一块重地,它为虚方法的动态调用搭起了桥梁。虚方法是可以被子类重写的类方法,而 vtable 则记录了它们的实现地址。当调用一个虚方法时,编译器会根据对象所属的类,从 vtable 中获取相应的实现地址,实现方法的动态绑定。

结语:底层结构体的磅礴魅力

通过探索 OC 底层结构体,我们揭开了 Objective-C 底层世界的神秘面纱。这些结构体构成了 OC 对象和类系统的根基,理解它们对于掌握 OC 底层编程至关重要。深入剖析这些结构体,我们可以更透彻地理解 OC 对象的创建、内存管理和方法调用等核心概念,进而提升我们的编程功力,纵横 Objective-C 的天地之间。

常见问题解答

1. OC 对象的本质是什么?
OC 对象本质上指向一个 objc_object 结构体,该结构体包含指向类结构体的指针。

2. 类结构体包含哪些信息?
类结构体包含类的元数据信息,包括类的名称、父类、协议、实例变量布局、方法列表、子类列表、缓存和虚函数表。

3. 实例变量布局如何描述实例变量?
实例变量布局通过编码前缀、偏移量和变量名称,描述了类的实例变量布局。

4. 方法列表中每个方法的结构是什么样的?
每个方法由一个结构体表示,包含方法的选择器、方法的参数类型和返回值类型的字符串描述,以及指向方法实现的指针。

5. 虚函数表是如何工作的?
虚函数表存储了虚方法的实现地址。当调用一个虚方法时,编译器会根据对象所属的类,从 vtable 中获取相应的实现地址,实现方法的动态绑定。