返回

objc_class 中的 cache 以及 sel-imp 原理揭秘

IOS

objc_class 中的 cache 以及 sel-imp 原理分析

前言

在探索 Objective-C 的内部运作机制时,深入了解 objc_class 结构对于理解其对象模型至关重要。本篇文章将重点分析 objc_class 中的 cache 以及 sel-imp 缓存原理。

objc_class 结构

Objective-C 类是由 objc_class 结构表示的,其中包含了类的元数据和方法表。objc_class 结构如下所示:

struct objc_class {
    Class isa;
    #if !__OBJC2__
    Class superclass;
    const char *name;
    long version;
    long info;
    long instance_size;
    long ivars;
    #else
    Class superclass;
    const char *name;
    long version;
    long info;
    long instance_size;
    long ivars;
    const char *weak_info;
    long bitfields;
    void **methodLists;
    Class *protocols;
    #endif
};

cache 变量

objc_class 结构中包含一个名为 cache 的变量,它是一个指向 cache_t 结构的指针。cache_t 结构如下所示:

typedef struct cache_t {
    long *locked;
    long *buckets;
    IMP *imp;
} cache_t;

cache_t 结构用于实现方法选择器 (sel) 到方法实现 (imp) 的缓存。它包含以下三个字段:

  • locked: 指向一个布尔值数组的指针,用于标记缓存桶是否已被锁定。
  • buckets: 指向一个哈希表数组的指针,其中每个桶存储一个 sel-imp 对。
  • imp: 指向一个方法实现数组的指针,其中每个元素都是一个方法的实现。

sel-imp 缓存原理

Objective-C 运行时使用 cache_t 结构来缓存 sel-imp 对。当第一次向类发送消息时,运行时会查找 cache_t 结构中相应的缓存桶。如果缓存桶中没有找到 sel-imp 对,则运行时会遍历类的所有方法表,寻找与 sel 匹配的方法。如果找到匹配的方法,则将 sel-imp 对添加到缓存桶中。

缓存 sel-imp 对可以提高方法调用的性能,因为运行时不必每次都遍历类的方法表。但是,为了确保缓存的一致性,在修改类的方法表时需要锁定缓存桶。

结论

深入了解 objc_class 结构中的 cachesel-imp 缓存原理对于理解 Objective-C 的对象模型至关重要。cache_t 结构通过缓存 sel-imp 对提高了方法调用的性能,从而减少了运行时遍历类的方法表的时间。