MST

星途 面试题库

面试题:Objective-C运行时类的结构中,category是如何存储和加载的?

在Objective-C运行时机制里,类的category在类结构中是怎样的存储形式,在加载时又经历了哪些过程,对类的方法列表有何影响?
46.5万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

1. 类的category在类结构中的存储形式

  • Category的数据结构:Category在Objective-C运行时用category_t结构体来表示。它包含了一些关键信息,例如指向类的指针Class cls,category的名称const char *name,方法列表method_list_t *instanceMethods,类方法列表method_list_t *classMethods,协议列表protocol_list_t *protocols等。
  • 存储位置:Category并没有像类的属性、方法等直接存储在类对象内部。它有自己独立的结构体,在运行时通过runtime机制与类关联起来。

2. 加载过程

  • 编译期:编译器会为每个category生成一个category_t结构体,包含了category中定义的方法、属性、协议等信息。
  • 运行期
    • dyld动态链接:当程序启动时,dyld动态链接器加载相关的动态库。
    • runtime加载:runtime开始处理类和category的加载。runtime会遍历所有的category,将它们的信息合并到对应的类中。具体来说,runtime会将category的方法列表、协议列表等添加到类的相应列表中。在加载category时,runtime会先处理类的主实现,然后再处理相关的category。

3. 对类的方法列表的影响

  • 方法添加:category中的实例方法会被添加到类的实例方法列表中,类方法会被添加到类的类方法列表中。
  • 方法覆盖(Method Swizzling):如果category中定义的方法与类本身或其他category中的方法同名,在运行时,后加载的category的方法会覆盖先加载的同名方法。这是因为runtime在合并方法列表时,后处理的category的方法会被放在方法列表的前面,在消息发送时,runtime会优先找到前面的方法并调用。需要注意的是,这种覆盖并不是真正意义上的替换原有方法的实现,而是在方法查找顺序上的调整。