美文网首页
iOS中,类,分类,拓展分别储存在哪里?

iOS中,类,分类,拓展分别储存在哪里?

作者: 博文得礼 | 来源:发表于2025-04-22 09:43 被阅读0次

在 iOS 中,类、分类(Category)、拓展(Extension)的存储位置与其数据类型和编译阶段有关,具体如下:

一、类(Class)的数据存储

类的信息分为 编译期定义的数据 和 运行时动态生成的数据,存储在不同区域:

1. 编译期数据(静态存储)

类名、继承关系、属性声明、方法声明 等信息存储在 Mach-O 文件 的 __DATA 段或 __TEXT 段(如 ro 数据)。

具体通过 class_ro_t 结构体(objc_class 中的 bits 字段指向)存储,属于 只读数据,存储在 内存的只读区域(如代码段)。

2. 运行时数据(动态存储)

方法实现、协议列表、关联对象 等运行时动态添加的数据,通过 class_rw_t 结构体(从 bits.data() 获取)管理,存储在 堆内存 或 数据段(可读写区域)。

类对象(objc_class 实例)本身存储在 堆内存,由 Runtime 管理生命周期。

二、分类(Category)的数据存储

分类是 运行时动态加载 的逻辑扩展,其数据存储特点:

1. 分类元数据

分类的方法、属性(通过 @property 结合关联对象实现)、协议等信息,编译后生成 category_t 结构体,存储在 Mach-O 文件 的 __DATA 段(如 __objc_catlist 节)。

运行时,Runtime 会将分类的 category_t 合并到类的 class_rw_t 中(方法列表、协议列表等),存储在类对象的 堆内存数据区。

2. 分类方法的存储

分类的实例方法和类方法实现,存储在 代码段(与类的方法实现一起),属于 只读数据。

若分类与类存在方法名冲突,分类方法会覆盖类的原方法(运行时方法查找顺序决定)。

三、拓展(Extension)的数据存储

拓展(匿名分类)是 编译期特性,本质是类的私有声明,存储特点:

1. 声明阶段

拓展中声明的属性(实例变量)、方法,在编译时直接合并到 类的 class_ro_t 结构体 中,与类的原始声明无异。

因此,拓展的 属性声明会生成实例变量,存储在类对象的 ro 数据中(只读区域),而 方法声明 存储在 class_ro_t 的方法列表中。

2. 实现阶段

拓展中声明的方法必须在 类的 .m 文件中实现,实现代码存储在 代码段(只读区域),与类的其他方法一起。

拓展无法像分类一样在运行时动态添加,属于类的 静态组成部分。

总结:存储位置对比

类型 编译期存储位置 运行时存储位置 数据性质

关键说明

• 分类与拓展的本质区别:

分类是 运行时扩展,拓展是 编译期绑定,前者通过 category_t 动态合并,后者直接编译到类结构中。

• 内存区域安全性:

只读数据(如 ro、代码段)存储在不可写区域,防止运行时篡改;可写数据(如 rw、关联对象)存储在堆或数据段,支持动态修改。

相关文章

网友评论

      本文标题:iOS中,类,分类,拓展分别储存在哪里?

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