返回
iOS OC类底层bits分析(上)
IOS
2023-11-23 22:12:41
iOS OC 类底层 bits 分析(上)
OC 类对象结构简介
在探讨 OC 类的内部结构之前,我们需要先了解一下 OC 类对象的结构。OC 类对象是一个包含有关类本身信息的数据结构,类似于 C++ 中的类模板。类对象的布局因平台和架构的不同而有所差异。
在 iOS 上,类对象通常具有以下结构:
struct objc_class {
Class isa; // 指向自身类型的指针
const char *name; // 类名
long version; // 类版本号
long info; // 类信息
long instance_size; // 实例大小
long ivar_layout; // 实例变量布局
long weak_ivar_layout; // 弱引用实例变量布局
const char **method_names; // 方法名列表
const void **method_imp; // 方法实现列表
const char **properties; // 属性列表
const char **ivars; // 实例变量列表
const int *ivar_offsets; // 实例变量偏移量列表
const int *weak_ivar_offsets; // 弱引用实例变量偏移量列表
void *protocols; // 遵循的协议列表
void *superclass; // 父类
void *cache; // 缓存数据
void *vtable; // 虚函数表
};
类对象布局详解
类名和版本:
name
字段存储着类名,是一个 C 风格字符串。version
字段存储着类的版本号,用于区分不同版本的类。
实例大小:
instance_size
字段存储着该类实例的大小,单位为字节。
方法列表和属性列表:
method_names
和method_imp
字段分别存储着该类的所有方法名和方法实现。properties
字段存储着该类的所有属性。
实例变量布局:
ivar_layout
字段存储着该类的所有实例变量的布局信息。ivar_offsets
字段存储着每个实例变量的偏移量,单位为字节。
弱引用实例变量布局:
weak_ivar_layout
字段存储着该类的所有弱引用实例变量的布局信息。weak_ivar_offsets
字段存储着每个弱引用实例变量的偏移量,单位为字节。
协议和父类:
protocols
字段存储着该类遵循的所有协议。superclass
字段存储着该类的父类。
缓存和虚函数表:
cache
字段存储着该类的缓存数据,用于优化方法调用。vtable
字段存储着该类的虚函数表,用于动态绑定。
isa 指针
isa 指针是一个指向类对象的指针,存储在每个 OC 对象的第一个成员变量中。通过 isa 指针,我们可以获取有关该对象所属类的所有信息。
我们可以使用 LLDB 命令 p $object->isa
来查看一个 OC 对象的 isa 指针指向的类对象。
小结
通过了解 OC 类对象的结构,我们可以更好地理解 OC 类的底层实现机制。在下一篇文章中,我们将继续深入探讨 OC 类的 bits 分析,重点关注实例变量和方法实现的存储结构。
常见问题解答
-
OC 类对象的结构在不同的平台和架构上是否相同?
- 不完全相同,不同的平台和架构可能略有差异。
-
类名是如何存储在类对象中的?
- 以 C 风格字符串的形式存储在
name
字段中。
- 以 C 风格字符串的形式存储在
-
实例变量是如何布局的?
- 实例变量按照声明顺序连续存储,偏移量存储在
ivar_offsets
字段中。
- 实例变量按照声明顺序连续存储,偏移量存储在
-
弱引用实例变量与普通实例变量有什么区别?
- 弱引用实例变量不会使对象保持活动状态,而普通实例变量会。
-
isa 指针指向什么?
- isa 指针指向该对象所属类的类对象。