侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

Objective-C 之 Runtime 类

2022-06-01 星期三 / 0 评论 / 0 点赞 / 152 阅读 / 67643 字

数据结构在获取一个对象所属的类时,返回值的类型是 Class- (Class)class;Class 代表一个类,它是指向一个类对象的指针typedef struct objc_class *Clas

数据结构

在获取一个对象所属的类时,返回值的类型是 Class

- (Class)class;

Class 代表一个类,它是指向一个类对象的指针

typedef struct objc_class *Class;

实际上,Class 是一个 objc_class 结构体类型指针的别名

struct objc_class : objc_object {    // Class ISA;    Class superclass;    cache_t cache;             // formerly cache pointer and vtable    class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags};

可以看到 objc_class 中有三个成员。

  • 首先,objc_class 是继承自 objc_object,也就是说类也是一个对象。其中从 objc_object 继承下来的成员 isa,它包含了当前类对象所属的元类的信息。

  • 其次,成员 superclass 指向了该类的父类

  • 接着,成员 cache 中缓存了最近调用过的方法

  • 最后,成员 bits 根据注释可以知道 bits = 指向 class_rw_t 类型结构体的指针 + 自定义的 rr/alloc 标识

cache_t

struct cache_t {    explicit_atomic<struct bucket_t *> _buckets;    explicit_atomic<mask_t> _mask;    uint16_t _occupied;};

用来缓存调用过方法的是一个 cache_t 类型的结构体,共有三个成员。

第一个成员 _buckets 是一个 bucket_t 类型的数组。

第二个成员 _mask 保存着总共申请用来缓存的数量。

第三个成员 _flags 用于在 64 位时,保存一些类的相关信息。

第四个成员 _occupied 保存着目前已经使用缓存的数量。

bucket_t

struct bucket_t {#if __arm64__    explicit_atomic<uintptr_t> _imp;    explicit_atomic<SEL> _sel;#else    explicit_atomic<SEL> _sel;    explicit_atomic<uintptr_t> _imp;#endif};

bucket_t 结构体中存储了键值对,其中 _imp 是一个函数指针,指向函数的具体实现,_sel 是方法名或者方法标识。也就说 _buckets 是一个哈希表,里面通过键值对的方式保存着调用过的方法。键为 SEL 类型,值为 IMP 类型。

SEL

typedef struct objc_selector *SEL;

从声明上看 SEL 是一个 objc_selector 结构体指针的别名;从实现中找,发现 SEL 是指向一个 char * 变量,也就是说其实它就是个映射到方法的 C 字符串,可以理解为是区分方法的 ID。

SEL 只与方法名有关:

  • 不同类中相同名字的方法所对应的方法选择器是相同的
  • 方法名相同而变量类型不同所对应的方法选择器也是相同的

IMP

#if !OBJC_OLD_DISPATCH_PROTOTYPEStypedef void (*IMP)(void /* id, SEL, ... */ ); #elsetypedef id _Nullable (*IMP)(id _Nonnull, SEL _Nonnull, ...); #endif

IMP 是一个函数指针,它指向函数的具体实现。

class_data_bits_t

bits 中保存着类的相关信息,它是一个 class_data_bits_t 类型的结构体,

struct class_data_bits_t {    // Values are the FAST_ flags above.    uintptr_t bits;};

这个结构体中的成员和 isa_t 结构体相同,都是通过一个 64 位的 bits 储存信息

// class is a Swift class from the pre-stable Swift ABI#define FAST_IS_SWIFT_LEGACY    (1UL<<0)// class is a Swift class from the stable Swift ABI#define FAST_IS_SWIFT_STABLE    (1UL<<1)// class or superclass has default retain/release/autorelease/retainCount///   _tryRetain/_isDeallocating/retainWeakReference/allowsWeakReference#define FAST_HAS_DEFAULT_RR     (1UL<<2)// data pointer#define FAST_DATA_MASK          0x00007ffffffffff8UL

通过定义的宏可以知道这些位都代表了什么含义

  • FAST_IS_SWIFT_LEGACY 是否是来自老版稳定 Swift ABI 的 Swift 类
  • FAST_IS_SWIFT_STABLE 是否是来自新版稳定 Swift ABI 的 Swift 类
  • FAST_HAS_DEFAULT_RR 当前类或者父类含有默认的 retain/release/autorelease/retainCount/_tryRetain/_isDeallocating/retainWeakReference/allowsWeakReference 方法
  • FAST_DATA_MASK 数据指针

搜索 FAST_DATA_MASK 的使用位置,可以找到一对取值/赋值方法

class_rw_t* data() const {    return (class_rw_t *)(bits & FAST_DATA_MASK);}void setData(class_rw_t *newData){    ASSERT(!data()  ||  (newData->flags & (RW_REALIZING | RW_FUTURE)));    // Set during realization or construction only. No locking needed.    // Use a store-release fence because there may be concurrent    // readers of data and data's contents.    uintptr_t newBits = (bits & ~FAST_DATA_MASK) | (uintptr_t)newData;    atomic_thread_fence(memory_order_release);    bits = newBits;}

通过这两方法,可以知道数据指针是一个 class_rw_t 类型的指针

class_rw_t

struct class_rw_t {    // Be warned that Symbolication knows the layout of this structure.    uint32_t flags;    uint16_t version;    uint16_t witness;    const class_ro_t *ro;    method_array_t methods;    property_array_t properties;    protocol_array_t protocols;    Class firstSubclass;    Class nextSiblingClass;    char *demangledName;}

结构体 class_rw_t 名称中的 rw 代表 readwrite,其中的成员 ro 是一个 class_ro_t 类型的指针,这里的 ro 代表 readonlyro 中存储了当前类在编译期就已经确定的属性、方法以及遵循的协议。而 class_rw_t 提供了运行时对类拓展的能力,其中的 methodspropertiesprotocols 保存着通过 Category 在运行时添加的方法、属性及协议。

成员 methodspropertiesprotocols 对应的 method_array_tproperty_array_tprotocol_array_t 类型都是继承自 list_array_tt<Element, List>,该类型可以保存三种类型的值:

  1. 空值;
  2. 指向单个列表的指针;
  3. 指向列表的指针数组。

通过第 3 种类型也就是二维数组类型,可以实现数据的扩展。例如,method_array_t 是一个数组,其中保存的元素是 method_list_t,而 method_list_t 也是一个数组,其中保存的元素是 method_t

class_ro_t

相对的,class_ro_t 保存的就是在编译期确定的数据。

struct class_ro_t {    uint32_t flags;    uint32_t instanceStart;    uint32_t instanceSize;#ifdef __LP64__    uint32_t reserved;#endif    const uint8_t * ivarLayout;        const char * name;    method_list_t * baseMethodList;    protocol_list_t * baseProtocols;    const ivar_list_t * ivars;    const uint8_t * weakIvarLayout;    property_list_t *baseProperties;};

结构体中的成员 baseMethodListbasePropertiesbaseProtocolsivar_list_t 对应的 method_list_tproperty_list_tprotocol_list_tivar_list_t 类型都是继承自 entsize_list_tt,一个泛型的数组结构,没有扩展功能。

类的初始化

类在运行时第一次初始化时会调用 realizeClass... 系列方法

ro = (const class_ro_t *)cls->data();if (ro->flags & RO_FUTURE) {    // This was a future class. rw data is already allocated.    rw = cls->data();    ro = cls->data()->ro;    cls->changeInfo(RW_REALIZED|RW_REALIZING, RW_FUTURE);} else {    // Normal class. Allocate writeable class data.    rw = (class_rw_t *)calloc(sizeof(class_rw_t), 1);    rw->ro = ro;    rw->flags = RW_REALIZED|RW_REALIZING;    cls->setData(rw);}

在该方法的实现中,可以知道在编译期间类的结构中的 class_data_bits_t *data 指向的是一个 class_ro_t *。在运行时的时候调用该初始化方法时,首先为 class_rw_t * 申请内存空间,然后将 class_ro_t * 赋值给 rw->ro,接着设置 class_rw_t * 的标志位标识状态,最后将创建好的 class_rw_t * 赋值给类结构。

分类

Category 提供了在运行时动态的向已经存在的类中添加方法、协议和属性的功能

typedef struct category_t *Category;
struct category_t {    const char *name;    classref_t cls;    struct method_list_t *instanceMethods;    struct method_list_t *classMethods;    struct protocol_list_t *protocols;    struct property_list_t *instanceProperties;    // Fields below this point are not always present on disk.    struct property_list_t *_classProperties;};

加载分类

static voidattachCategories(Class cls, const locstamped_category_t *cats_list, uint32_t cats_count,                 int flags){    constexpr uint32_t ATTACH_BUFSIZ = 64;    method_list_t   *mlists[ATTACH_BUFSIZ];    uint32_t mcount = 0;    bool fromBundle = NO;    bool isMeta = (flags & ATTACH_METACLASS);    auto rw = cls->data();    for (uint32_t i = 0; i < cats_count; i++) {        auto& entry = cats_list[i];        method_list_t *mlist = entry.cat->methodsForMeta(isMeta);        if (mlist) {            if (mcount == ATTACH_BUFSIZ) {                prepareMethodLists(cls, mlists, mcount, NO, fromBundle);                rw->methods.attachLists(mlists, mcount);                mcount = 0;            }            mlists[ATTACH_BUFSIZ - ++mcount] = mlist;            fromBundle |= entry.hi->isBundle();        }    }    if (mcount > 0) {        prepareMethodLists(cls, mlists + ATTACH_BUFSIZ - mcount, mcount, NO, fromBundle);        rw->methods.attachLists(mlists + ATTACH_BUFSIZ - mcount, mcount);        if (flags & ATTACH_EXISTING) flushCaches(cls);    }}

原来的方法中包含了对分类中方法、代理和属性的处理,但原理相同,为了减少篇幅,只保留对方法的处理:

  • 声明一个大小为 64,元素类型为 method_list_t * 的二维数组类型的临时变量 mlists
  • 遍历分类数组,获取分类中的方法列表 mlist,从后向前的添加到 mlists
  • 如果 mlists 数组在遍历过程中存满,则合并到 rw->methods 中,否则等待遍历完合并

合并方法

void attachLists(List* const * addedLists, uint32_t addedCount) {        if (addedCount == 0) return;        if (hasArray()) {            // many lists -> many lists            uint32_t oldCount = array()->count;            uint32_t newCount = oldCount + addedCount;            setArray((array_t *)realloc(array(), array_t::byteSize(newCount)));            array()->count = newCount;            memmove(array()->lists + addedCount, array()->lists,                     oldCount * sizeof(array()->lists[0]));            memcpy(array()->lists, addedLists,                    addedCount * sizeof(array()->lists[0]));        }        else if (!list  &&  addedCount == 1) {            // 0 lists -> 1 list            list = addedLists[0];        }         else {            // 1 list -> many lists            List* oldList = list;            uint32_t oldCount = oldList ? 1 : 0;            uint32_t newCount = oldCount + addedCount;            setArray((array_t *)malloc(array_t::byteSize(newCount)));            array()->count = newCount;            if (oldList) array()->lists[addedCount] = oldList;            memcpy(array()->lists, addedLists,                    addedCount * sizeof(array()->lists[0]));        }    }

在合并时,大致有两种情况。一种是当前数组中为空,那就直接指向新添加的数组;另一种是当前数组中已经有数据:

  1. 先通过 realloc() 方法为原数组扩充空间
  2. 再将原数组的元素利用 memmove() 方法移动到新申请空间的后面
  3. 最后使用 memcpy() 方法把新数组复制到新空间的前面

方法覆盖

通过上面两段代码,可以发现两点:

  1. 分类中如果重写了方法,并不会覆盖原有方法
  2. 之所以在使用时出现“覆盖”原方法的现象,是因为在方法列表中分类中的方法被添加到了原方法的前面
  3. 如果某个类的多个分类都重写了同一个方法,那么,最后执行的是最后被遍历到的分类(也就是最后被添加到项目中的分类)中的方法

函数

objc_class

data

获取类中的数据

// 返回值是一个 class_rw_t 类型的指针,说明类中的数据是以 class_rw_t 类型保存的class_rw_t *data() const {    // 通过调用成员 bits 的公共函数 data() 获取数据    return bits.data();}

setData

设置类中的数据

// 设置值要求是一个 class_rw_t 类型的指针void setData(class_rw_t *newData) {    // 通过调用成员 bits 的公共函数 setData() 设置数据    bits.setData(newData);}

setInfo

设置标志位信息

void setInfo(uint32_t set) {    // 必须满足要么是一个未实现的懒加载类,要么已经实现    ASSERT(isFuture()  ||  isRealized());    // 先调用 data 函数获取类的 class_rw_t 实例数据    // 再调动 class_rw_t 实例的 setFlags 函数设置标志位信息    data()->setFlags(set);}

clearInfo

清除标志位信息

void clearInfo(uint32_t clear) {    // 必须满足要么是一个未实现的懒加载类,要么已经实现    ASSERT(isFuture()  ||  isRealized());    // 先调用 data 函数获取类的 class_rw_t 实例数据    // 再调动 class_rw_t 实例的 clearFlags 函数清除标志位信息    data()->clearFlags(clear);}

changeInfo

设置和清除标志位信息

void changeInfo(uint32_t set, uint32_t clear) {    // 必须满足要么是一个未实现的懒加载类,要么已经实现    ASSERT(isFuture()  ||  isRealized());    // 要设置的标志位和要清除的标志位不能是同一个    ASSERT((set & clear) == 0);    // 先调用 data 函数获取类的 class_rw_t 实例数据    // 再调动 class_rw_t 实例的 changeFlags 函数设置和清除标志位信息    data()->changeFlags(set, clear);}

hasCustomRR

获取当前类及其超类是否自定义了 retain/release/autorelease/retainCount/_tryRetain/_isDeallocating/retainWeakReference/allowsWeakReference 这些方法之一

bool hasCustomRR() const {    // 调用成员 bits 的 getBit 函数获取 FAST_HAS_DEFAULT_RR 标志位的数据    return !bits.getBit(FAST_HAS_DEFAULT_RR);}

setHasDefaultRR

标识当前类及其超类没有自定义retain/release/autorelease/retainCount/_tryRetain/_isDeallocating/retainWeakReference/allowsWeakReference 这些方法之一

void setHasDefaultRR() {    // 调用成员 bits 的 setBits 函数设置 FAST_HAS_DEFAULT_RR 标志位的数据    bits.setBits(FAST_HAS_DEFAULT_RR);}

setHasCustomRR

标识当前类及其超类自定义了retain/release/autorelease/retainCount/_tryRetain/_isDeallocating/retainWeakReference/allowsWeakReference 这些方法之一

void setHasCustomRR() {    // 调用成员 bits 的 clearBits 函数将 FAST_HAS_DEFAULT_RR 标志位的数据置零    bits.clearBits(FAST_HAS_DEFAULT_RR);}

hasCustomAWZ

获取当前类及其超类是否自定义了 alloc/allocWithZone: 这些方法之一

bool hasCustomAWZ() const {    // 调用成员 cache 的 getBit 函数获取 FAST_CACHE_HAS_DEFAULT_AWZ 标志位的数据    return !cache.getBit(FAST_CACHE_HAS_DEFAULT_AWZ);}

setHasDefaultAWZ

标识当前类及其超类没有自定义 alloc/allocWithZone: 这些方法之一

void setHasDefaultAWZ() {    // 调用成员 cache 的 setBits 函数设置 FAST_CACHE_HAS_DEFAULT_AWZ 标志位的数据    cache.setBit(FAST_CACHE_HAS_DEFAULT_AWZ);}

setHasCustomAWZ

标识当前类及其超类自定义了 alloc/allocWithZone: 这些方法之一

void setHasCustomAWZ() {    // 调用成员 cache 的 clearBits 函数将 FAST_CACHE_HAS_DEFAULT_AWZ 标志位的数据置零    cache.clearBit(FAST_CACHE_HAS_DEFAULT_AWZ);}

hasCustomCore

获取当前类及其超类是否自定义了 new/self/class/respondsToSelector/isKindOfClass 这些方法之一

bool hasCustomCore() const {    // 调用成员 cache 的 getBit 函数获取 FAST_CACHE_HAS_DEFAULT_CORE 标志位的数据    return !cache.getBit(FAST_CACHE_HAS_DEFAULT_CORE);}

setHasDefaultCore

标识当前类及其超类没有自定义 new/self/class/respondsToSelector/isKindOfClass 这些方法之一

void setHasDefaultCore() {    // 调用成员 cache 的 setBits 函数设置 FAST_CACHE_HAS_DEFAULT_CORE 标志位的数据    return cache.setBit(FAST_CACHE_HAS_DEFAULT_CORE);}

setHasCustomCore

标识当前类及其超类自定义了 new/self/class/respondsToSelector/isKindOfClass 这些方法之一

void setHasCustomCore() {    // 调用成员 cache 的 clearBits 函数将 FAST_CACHE_HAS_DEFAULT_CORE 标志位的数据置零    return cache.clearBit(FAST_CACHE_HAS_DEFAULT_CORE);}

hasCxxCtor

获取当前类及其超类是否有 .cxx_construct C++ 构造方法的实现

bool hasCxxCtor() {    // 当前类必须已经实现    ASSERT(isRealized());    // 调用成员 cache 的 getBit 函数获取 FAST_CACHE_HAS_CXX_CTOR 标志位的数据    return cache.getBit(FAST_CACHE_HAS_CXX_CTOR);}

setHasCxxCtor

标识当前类及其超类有 .cxx_construct C++ 构造方法的实现

void setHasCxxCtor() {    // 调用成员 cache 的 setBits 函数设置 FAST_CACHE_HAS_CXX_CTOR 标志位的数据    cache.setBit(FAST_CACHE_HAS_CXX_CTOR);}

hasCxxDtor

获取当前类及其超类是否有 .cxx_destruct C++ 析构方法的实现

bool hasCxxDtor() {    // 当前类必须已经实现    ASSERT(isRealized());    // 调用成员 cache 的 getBit 函数获取 FAST_CACHE_HAS_CXX_DTOR 标志位的数据    return cache.getBit(FAST_CACHE_HAS_CXX_DTOR);}

setHasCxxDtor

标识当前类及其超类有 .cxx_destruct C++ 析构方法的实现

void setHasCxxDtor() {    // 调用成员 cache 的 setBits 函数设置 FAST_CACHE_HAS_CXX_DTOR 标志位的数据    cache.setBit(FAST_CACHE_HAS_CXX_DTOR);}

instancesRequireRawIsa

获取类的实例对象是否需要原始 isa(isa 直接指向类)

bool instancesRequireRawIsa() {    // 调用成员 cache 的 getBit 函数获取 FAST_CACHE_REQUIRES_RAW_ISA 标志位的数据    return cache.getBit(FAST_CACHE_REQUIRES_RAW_ISA);}

setInstancesRequireRawIsa

标识类的实例对象需要原始 isa(isa 直接指向类)

void setInstancesRequireRawIsa() {    // 调用成员 cache 的 setBits 函数设置 FAST_CACHE_REQUIRES_RAW_ISA 标志位的数据    cache.setBit(FAST_CACHE_REQUIRES_RAW_ISA);}

setInstancesRequireRawIsaRecursively

将当前类及其所有子类,全部标识为其类的实例对象需要原始 isa(isa 直接指向类)

void setInstancesRequireRawIsaRecursively(bool inherited = false);void objc_class::setInstancesRequireRawIsaRecursively(bool inherited){    // 获取当前类对象    Class cls = (Class)this;    // 加锁    runtimeLock.assertLocked();        // 如果当前类的实例对象已经被要求是原始 isa,就直接返回    if (instancesRequireRawIsa()) return;        // 遍历当前类及其子类    foreach_realized_class_and_subclass(cls, [=](Class c){        // 如果该类的实例对象已经被要求是原始 isa,就直接跳过        if (c->instancesRequireRawIsa()) {            return false;        }        // 标识该类的实例对象需要是原始 isa 类型        c->setInstancesRequireRawIsa();        // 打印日志相关        if (PrintRawIsa) c->printInstancesRequireRawIsa(inherited || c != cls);        return true;    });}

printInstancesRequireRawIsa

void printInstancesRequireRawIsa(bool inherited);voidobjc_class::printInstancesRequireRawIsa(bool inherited){    // 必须已经标识为要打印原始 isa    ASSERT(PrintRawIsa);    // 必须是该类的实例对象已经被要求是原始 isa    ASSERT(instancesRequireRawIsa());    // 打印原始 isa 相关信息    _objc_inform("RAW ISA:  %s%s%s", nameForLogging(),                  isMetaClass() ? " (meta)" : "",                  inherited ? " (inherited)" : "");}

canAllocNonpointer

获取当前类的实例对象可否以 Nonpointer 类型创建

bool canAllocNonpointer() {    // 必须是正常类,而非懒加载类    ASSERT(!isFuture());    // 如果该类的实例对象不要求是原始 isa 类型就可以用 Nonpointer 类型    return !instancesRequireRawIsa();}

isSwiftStable

获取当前类是否为 Swift 最新稳定类

bool isSwiftStable() {    // 调用成员 bits 的 isSwiftStable 函数获取    return bits.isSwiftStable();}

isSwiftLegacy

获取当前类是否为 Swift 老版稳定类

bool isSwiftLegacy() {    // 调用成员 bits 的 isSwiftLegacy 函数获取    return bits.isSwiftLegacy();}

isAnySwift

获取当前类是否为 Swift 类

bool isAnySwift() {    // 调用成员 bits 的 isAnySwift 函数获取    return bits.isAnySwift();}

isSwiftStable_ButAllowLegacyForNow

获取当前类是否为 Swift 类

bool isSwiftStable_ButAllowLegacyForNow() {    // 调用成员 bits 的 isSwiftStable_ButAllowLegacyForNow 函数获取    // 其中 isSwiftStable_ButAllowLegacyForNow 函数内部调用了 isAnySwift 函数    return bits.isSwiftStable_ButAllowLegacyForNow();}

isStubClass

获取当前类是否为存根类

bool isStubClass() const {    // 获取类对象的 isa 数据    uintptr_t isa = (uintptr_t)isaBits();    // 如果 isa 数据在 5 位以内就是存根类    return 1 <= isa && isa < 16;}

isUnfixedBackwardDeployingStableSwift

判断是否为未修复的向后兼容的老版 Swift 稳定类

bool isUnfixedBackwardDeployingStableSwift() {    // Only classes marked as Swift legacy need apply.    // 只处理老版 Swift 稳定类    if (!bits.isSwiftLegacy()) return false;    // Check the true legacy vs stable distinguisher.    // The low bit of Swift's ClassFlags is SET for true legacy    // and UNSET for stable pretending to be legacy.    // 获取 Swift 类的标志位。即类对象地址的第 1 位的值    uint32_t swiftClassFlags = *(uint32_t *)(&bits + 1);    // 根据标志位判断是否为真的老版 Swift 稳定类    bool isActuallySwiftLegacy = bool(swiftClassFlags & 1);    // 返回结果    return !isActuallySwiftLegacy;}

fixupBackwardDeployingStableSwift

修复向后兼容的老版 Swift 稳定类的标志位

void fixupBackwardDeployingStableSwift() {    // 如果是未修复的向后兼容的老版 Swift 稳定类    if (isUnfixedBackwardDeployingStableSwift()) {        // Class really is stable Swift, pretending to be pre-stable.        // Fix its lie.        // 设置其标志位为稳定版 Swift 类,并清除老版 Swift 稳定版标志位        bits.setIsSwiftStable();    }}

swiftMetadataInitializer

获取 Swift 元类初始化器

_objc_swiftMetadataInitializer swiftMetadataInitializer() {    // 调用成员 bits 的 swiftMetadataInitializer 函数获取    return bits.swiftMetadataInitializer();}

hasAutomaticIvars

获取该类的成员变量是否为自动布局

bool hasAutomaticIvars() {    // 通过 data 函数获取保存在 ro 成员中的 flags 标志位数据    // 获取其标志位 RO_IS_ARC 和 RO_HAS_WEAK_WITHOUT_ARC 中保存的数据    // 如果标志位标示该类是用 ARC 编译的类,或者类不是 ARC 编译的类,但具有 ARC 样式的弱 ivar 布局,就返回 true    return data()->ro->flags & (RO_IS_ARC | RO_HAS_WEAK_WITHOUT_ARC);}

isARC

获取该类的成员变量是否由 ARC 管理

bool isARC() {    // 通过 data 函数获取保存在 ro 成员中的 flags 标志位数据    // 获取其标志位 RO_IS_ARC 中保存的数据    return data()->ro->flags & RO_IS_ARC;}

forbidsAssociatedObjects

获取该类是否禁止其实例对象关联对象

bool forbidsAssociatedObjects() {    // 通过 data 函数获取保存在 ro 成员中的 flags 标志位数据    // 获取其标志位 RW_FORBIDS_ASSOCIATED_OBJECTS 中保存的数据    return (data()->flags & RW_FORBIDS_ASSOCIATED_OBJECTS);}

shouldGrowCache

获取该类是否要增加缓存

bool shouldGrowCache() {    // 直接返回 true,也就是一定会增加缓存    return true;}

setShouldGrowCache

设置该类是否要增加缓存

void setShouldGrowCache(bool) {    // 无实现    // fixme good or bad for memory use?}

isInitializing

获取该类是否正在初始化

bool isInitializing() {    // 通过 getMeta 函数获取该类的元类    // 通过 data 函数获取该类元类的数据    // 获取其标志位 RW_INITIALIZING 中保存的数据    return getMeta()->data()->flags & RW_INITIALIZING;}

setInitializing

设置该类是否正在初始化的状态

void setInitializing() {    // 当前类不能是元类    ASSERT(!isMetaClass());    // 通过 ISA 函数获取该类的元类    // 通过 setInfo 函数设置其元类 RW_INITIALIZING 标志位的数据    ISA()->setInfo(RW_INITIALIZING);}

isInitialized

获取该类是否已经初始化

bool isInitialized() {    // 通过 getMeta 函数获取该类的元类    // 通过 data 函数获取该类元类的数据    // 获取其标志位 RW_INITIALIZED 中保存的数据    return getMeta()->data()->flags & RW_INITIALIZED;}

setInitialized

设置该类是否已经初始化的状态

void setInitialized();void objc_class::setInitialized(){    Class metacls;    Class cls;    // 当前类不能是元类    ASSERT(!isMetaClass());    // 获取当前类的类对象并保存到临时变量中    cls = (Class)this;    // 获取当前类的元类并保存到临时变量中    metacls = cls->ISA();    // 加锁    mutex_locker_t lock(runtimeLock);    // Special cases:    // - NSObject AWZ  class methods are default.    // - NSObject RR   class and instance methods are default.    // - NSObject Core class and instance methods are default.    // adjustCustomFlagsForMethodChange() also knows these special cases.    // attachMethodLists() also knows these special cases.    // 扫描当前类的 +alloc / +allocWithZone: 方法是否为默认实现,并设置标志位进行标识    objc::AWZScanner::scanInitializedClass(cls, metacls);    // 扫描当前类的 retain/release/autorelease/retainCount/_tryRetain/_isDeallocating/retainWeakReference/allowsWeakReference 方法是否为默认实现,并设置标志位进行标识    objc::RRScanner::scanInitializedClass(cls, metacls);    // 扫描当前类的 +new, ±class, ±self, ±isKindOfClass:, ±respondsToSelector 方法是否为默认实现,并设置标志位进行标识    objc::CoreScanner::scanInitializedClass(cls, metacls);    // Update the +initialize flags.    // Do this last.    // 通过 changeInfo 函数设置其元类 RW_INITIALIZED 标志位的数据,并清除 RW_INITIALIZING 标志位的数据    metacls->changeInfo(RW_INITIALIZED, RW_INITIALIZING);}

isLoadable

获取该类是否为可加载的

bool isLoadable() {    // 必须是已经实现的类    ASSERT(isRealized());    // 任何一个类都注册了 +load 方法,所以都是可加载的,就返回 true    return true;  // any class registered for +load is definitely loadable}

getLoadMethod

获取当前类的 +load 方法实现

IMP getLoadMethod();IMP objc_class::getLoadMethod(){    // 加锁    runtimeLock.assertLocked();    const method_list_t *mlist;    // 当前类必须已实现    ASSERT(isRealized());    // 当前类对象所属的类必须已实现    ASSERT(ISA()->isRealized());    // 当前类不能是元类    ASSERT(!isMetaClass());    // 当前类对象所属的类必须是元类    ASSERT(ISA()->isMetaClass());    // 通过 ISA 函数获取该类的元类    // 通过 data 函数设置其元类数据    // 通过调用其元类 ro 成员的 baseMethods 函数获取在编译时生成的方法列表    mlist = ISA()->data()->ro->baseMethods();    // 遍历类方法列表,如果类方法的 SEL 为 load,就返回其 IMP    if (mlist) {        for (const auto& meth : *mlist) {            const char *name = sel_cname(meth.name);            if (0 == strcmp(name, "load")) {                return meth.imp;            }        }    }    return nil;}

isRealized

获取该类是否已实现

bool isRealized() const {    // 前提为当前类不是存根类    // 通过 data 函数获取该类的数据    // 获取其标志位 RW_REALIZED 中保存的数据    return !isStubClass() && (data()->flags & RW_REALIZED);}

isFuture

获取该类是否为懒加载类

bool isFuture() const {    // 通过 data 函数获取该类的数据    // 获取其标志位 RW_FUTURE 中保存的数据    return data()->flags & RW_FUTURE;}

isMetaClass

获取该类是否为元类

bool isMetaClass() {    // 当前类必须存在    ASSERT(this);    // 当前类必须已实现    ASSERT(isRealized());#if FAST_CACHE_META    // 通过其 cache 成员的 getBit 函数获取标志位 FAST_CACHE_META 中保存的数据    return cache.getBit(FAST_CACHE_META);#else    return data()->ro->flags & RO_META;#endif}

isMetaClassMaybeUnrealized

获取该类是否为元类,但该类可能还未实现

bool isMetaClassMaybeUnrealized() {    // 调用成员 bits 的 safe_ro 函数安全的获取其编译时产生 ro 数据    // 获取其标志位 RO_META 中保存的数据    return bits.safe_ro()->flags & RO_META;}

getMeta

获取该类的元类

Class getMeta() {    // 如果当前类就是元类,便返回自己    if (isMetaClass()) return (Class)this;    // 否则通过 ISA 函数获取其元类    else return this->ISA();}

isRootClass

获取该类是否为根类

bool isRootClass() {    // 如果当前类的 superclass 成员为空,那当前类便是根类    return superclass == nil;}

isRootMetaclass

获取该类是否为根元类

bool isRootMetaclass() {    // 如果当前类对象所属的类就是自己,那当前类便是根元类    return ISA() == (Class)this;}

mangledName

获取该类的修饰别名

const char *mangledName() {     // fixme can't assert locks here    // 当前类必须存在    ASSERT(this);    if (isRealized()  ||  isFuture()) {        // 如果当前类已实现,或者是一个懒加载类        // 通过 data 函数获取保存在 ro 成员中 name 的数据        return data()->ro->name;    } else {        // 否则,先通过 data 函数获取 class_ro_t 类型的数据,然后获取数据中 name 的值        return ((const class_ro_t *)data())->name;    }}

demangledName

获取该类的解析别名

const char *demangledName();mutex_t DemangleCacheLock;static objc::DenseSet<const char *> *DemangleCache;const char *objc_class::demangledName(){    // Return previously demangled name if available.    // 如果当前类已实现,或者为懒加载类    if (isRealized()  ||  isFuture()) {        // 通过 data 函数获取该类的数据        // 获取数据中成员 demangledName 保存的值        // 如果有值的话,直接返回        if (data()->demangledName) return data()->demangledName;    }    // Try demangling the mangled name.    // 获取当前类的修饰别名    const char *mangled = mangledName();    // 生成符合 Swift-v1-mangled 样式的解析别名    char *de = copySwiftV1DemangledName(mangled);    // 如果当前类已实现,或者为懒加载类    if (isRealized()  ||  isFuture()) {        // Class is already realized or future.         // Save demangling result in rw data.        // We may not own runtimeLock so use an atomic operation instead.        // 将生成的解析别名保存到 rw 的 demangledName 成员中        if (! OSAtomicCompareAndSwapPtrBarrier(nil, (void*)(de ?: mangled),                                                (void**)&data()->demangledName))         {            // 如果没保存成功,就将解析别名释放掉            if (de) free(de);        }        // 返回即通过        return data()->demangledName;    }    // Class is not yet realized.    // 如果没能生成符合 Swift-v1-mangled 样式的解析别名,就直接返回当前类的修饰别名    if (!de) {        // Name is not mangled. Return it without caching.        return mangled;    }    // Class is not yet realized and name is mangled.    // Allocate the name but don't save it in the class.    // Save the name in a side cache instead to prevent leaks.    // When the class is actually realized we may allocate a second    // copy of the name, but we don't care.    // (Previously we would try to realize the class now and save the    // name there, but realization is more complicated for Swift classes.)    // Only objc_copyClassNamesForImage() should get here.    // fixme lldb's calls to class_getName() can also get here when    // interrogating the dyld shared cache. (rdar://27258517)    // fixme runtimeLock.assertLocked();    // fixme ASSERT(realize);    const char *cached;    {        // 加锁        mutex_locker_t lock(DemangleCacheLock);        // 如果没有 DemangleCache 容器,就生成一个        if (!DemangleCache) {            DemangleCache = new objc::DenseSet<const char *>{};        }        // 将解析别名插入到 DemangleCache 首位        cached = *DemangleCache->insert(de).first;    }    // 如果没能成功缓存,就将解析别名释放掉    if (cached != de) free(de);    // 返回缓存中保存的解析别名    return cached;}

nameForLogging

获取该类用于显示/打印的名称

const char *nameForLogging();const char *objc_class::nameForLogging(){    // Handle the easy case directly.    // 如果当前类已实现,或者为懒加载类    if (isRealized()  ||  isFuture()) {        // 通过 data 函数获取该类的数据中成员 demangledName 有值的话直接返回        if (data()->demangledName) return data()->demangledName;    }    char *result;    // 获取当前类的修饰别名    const char *name = mangledName();    // 获取当前类符合 Swift-v1-mangled 样式的解析别名    char *de = copySwiftV1DemangledName(name);    // 如果有解析别名,就返回解析别名    if (de) result = de;    // 否则就返回修饰别名    else result = strdup(name);    // 将名称保存在线程本地FIFO缓冲区中    saveTemporaryString(result);    // 返回结果    return result;}

unalignedInstanceStart

获取该类未经过字节对齐处理前的成员变量布局的开始位置

uint32_t unalignedInstanceStart() const {    // 当前类必须已实现    ASSERT(isRealized());    // 通过 data 函数获取该类的数据    // 获取数据中的 ro 成员    // 返回 ro 成员 instanceStart 中保存的值    return data()->ro->instanceStart;}

alignedInstanceStart

获取该类已经过对齐处理后的成员变量布局的开始位置

uint32_t alignedInstanceStart() const {    // 对当前类未经过字节对齐处理前的成员变量布局的开始位置进行字节对齐处理,并返回    return word_align(unalignedInstanceStart());}

unalignedInstanceSize

获取该类未经过字节对齐处理前的实例对象内存布局的大小

uint32_t unalignedInstanceSize() const {    // 当前类必须已实现    ASSERT(isRealized());    // 通过 data 函数获取该类的数据    // 获取数据中的 ro 成员    // 返回 ro 成员 instanceSize 中保存的值    return data()->ro->instanceSize;}

alignedInstanceSize

获取该类已经过对齐处理后的实例对象内存布局的大小

uint32_t alignedInstanceSize() const {    // 对当前类未经过字节对齐处理前的实例对象内存布局的大小进行字节对齐处理,并返回    return word_align(unalignedInstanceSize());}

instanceSize

获取该类实例对象占用的内存大小

size_t instanceSize(size_t extraBytes) const {    // 调用成员 cache 的 hasFastInstanceSize 函数获取实例对象内存布局的大小,如果有就直接返回    if (fastpath(cache.hasFastInstanceSize(extraBytes))) {        return cache.fastInstanceSize(extraBytes);    }        // 获取当前类已经过对齐处理后的实例对象内存布局的大小,并加上传入的参数    size_t size = alignedInstanceSize() + extraBytes;    // CF requires all objects be at least 16 bytes.    // 实例对象内存布局的大小最小为 16 字节    if (size < 16) size = 16;    // 返回大小    return size;}

setInstanceSize

设置该类实例对象占用的内存大小

void setInstanceSize(uint32_t newSize) {    // 当前类必须已实现    ASSERT(isRealized());    // 当前类设置过正在实现标识    ASSERT(data()->flags & RW_REALIZING);    // 如果新大小与 instanceSize 中保存的不同    if (newSize != data()->ro->instanceSize) {        // rw 的 ro 成员必须是 class_ro_t 类型的数据        ASSERT(data()->flags & RW_COPIED_RO);        // 将新数据保存到 instanceSize 中         *const_cast<uint32_t *>(&data()->ro->instanceSize) = newSize;    }    // 调用成员 cache 的 setFastInstanceSize 函数保存新的实例对象内存大小    cache.setFastInstanceSize(newSize);}

cache_t

emptyBuckets

获取一个空容器

static bucket_t *emptyBuckets();struct bucket_t *cache_t::emptyBuckets(){       // 获取一个空容器,转换成 bucket_t * 类型后返回    return (bucket_t *)&_objc_empty_cache;}

buckets

获取当前容器

struct bucket_t *buckets();struct bucket_t *cache_t::buckets() {    // 调用成员 `_buckets` 的 load 函数获取当前正在使用的容器    return _buckets.load(memory_order::memory_order_relaxed);}

mask

获取当前缓存大小

mask_t mask();mask_t cache_t::mask() {    // 调用成员 `_mask` 的 load 函数获取当前的缓存大小    return _mask.load(memory_order::memory_order_relaxed);}

occupied

获取当前已使用多少缓存

mask_t occupied();mask_t cache_t::occupied() {    // 直接返回成员 `_occupied`     return _occupied;}

incrementOccupied

增加缓存的数量

void incrementOccupied();void cache_t::incrementOccupied() {    // 成员 `_occupied` 计数 +1    _occupied++;}

setBucketsAndMask

重新设置容器和掩码

void setBucketsAndMask(struct bucket_t *newBuckets, mask_t newMask);void cache_t::setBucketsAndMask(struct bucket_t *newBuckets, mask_t newMask){    // objc_msgSend uses mask and buckets with no locks.    // It is safe for objc_msgSend to see new buckets but old mask.    // (It will get a cache miss but not overrun the buckets' bounds).    // It is unsafe for objc_msgSend to see old buckets and new mask.    // Therefore we write new buckets, wait a lot, then write new mask.    // objc_msgSend reads mask first, then buckets.#ifdef __arm__    // ensure other threads see buckets contents before buckets pointer    mega_barrier();    _buckets.store(newBuckets, memory_order::memory_order_relaxed);        // ensure other threads see new buckets before new mask    mega_barrier();        _mask.store(newMask, memory_order::memory_order_relaxed);    _occupied = 0;#elif __x86_64__ || i386    // ensure other threads see buckets contents before buckets pointer    // 保存新的容器    _buckets.store(newBuckets, memory_order::memory_order_release);        // ensure other threads see new buckets before new mask    // 保存新的掩码    _mask.store(newMask, memory_order::memory_order_release);    // 缓存计数置空    _occupied = 0;#else#error Don't know how to do setBucketsAndMask on this architecture.#endif}

initializeToEmpty

初始化缓存

void initializeToEmpty();void cache_t::initializeToEmpty(){    // 将当前内存中所有字节置空    bzero(this, sizeof(*this));    // 将容器置空    _buckets.store((bucket_t *)&_objc_empty_cache, memory_order::memory_order_relaxed);}

capacity

获取当前缓存容量

unsigned capacity();unsigned cache_t::capacity(){    // 调用 mask 获取缓存大小,如果有就 +1 后返回,没有就返回 0    return mask() ? mask()+1 : 0; }

isConstantEmptyCache

获取当前缓存是否为空

bool isConstantEmptyCache();bool cache_t::isConstantEmptyCache(){    // 一共有两个判断条件    // 一个是没有使用量    // 一个是空容器    return         occupied() == 0  &&          buckets() == emptyBucketsForCapacity(capacity(), false);}

canBeFreed

获取当前缓存是否可以释放

bool canBeFreed();bool cache_t::canBeFreed(){    // 如果缓存不为空,就可以释放    return !isConstantEmptyCache();}

getBit

获取指定标志位数据

bool getBit(uint16_t flags) const {    // 通过位与获取成员 _flags 中指定位的数据    return _flags & flags;}

setBit

设置指定标志位数据

void setBit(uint16_t set) {    // 原子性的设置成员 _flags 中指定位的数据    __c11_atomic_fetch_or((_Atomic(uint16_t) *)&_flags, set, __ATOMIC_RELAXED);}

clearBit

清空指定标志位数据

void clearBit(uint16_t clear) {    // 原子性的清空成员 _flags 中指定位的数据    __c11_atomic_fetch_and((_Atomic(uint16_t) *)&_flags, ~clear, __ATOMIC_RELAXED);}

hasFastInstanceSize

是否保存有快速获取实例变量的内存布局大小

bool hasFastInstanceSize(size_t extra) const{    // 如果参数 extra 是编译时常量,并且为 0,那么就取成员 _flags 掩码 FAST_CACHE_ALLOC_MASK16 的值    if (__builtin_constant_p(extra) && extra == 0) {        return _flags & FAST_CACHE_ALLOC_MASK16;    }    // 否则就取成员 _flags 掩码 FAST_CACHE_ALLOC_MASK 的值    return _flags & FAST_CACHE_ALLOC_MASK;}

fastInstanceSize

快速获取实例变量的内存布局大小

size_t fastInstanceSize(size_t extra) const{    // 成员 _flags 中必须有保存    ASSERT(hasFastInstanceSize(extra));    if (__builtin_constant_p(extra) && extra == 0) {        // 如果参数 extra 是编译时常量,并且为 0,那么就取成员 _flags 掩码 FAST_CACHE_ALLOC_MASK16 的值        return _flags & FAST_CACHE_ALLOC_MASK16;    } else {        // 否则就取成员 _flags 掩码 FAST_CACHE_ALLOC_MASK 的值        // 再加上传入的参数        // 接着减去通过 setFastInstanceSize 添加的 FAST_CACHE_ALLOC_DELTA16        // 最后通过 align16 函数对结果进行 16 字节对齐        size_t size = _flags & FAST_CACHE_ALLOC_MASK;        // remove the FAST_CACHE_ALLOC_DELTA16 that was added        // by setFastInstanceSize        return align16(size + extra - FAST_CACHE_ALLOC_DELTA16);    }}

setFastInstanceSize

设置快速获取实例变量的内存布局大小

void setFastInstanceSize(size_t newSize){    // Set during realization or construction only. No locking needed.    // 通过位与 FAST_CACHE_ALLOC_MASK 的反码,将成员 _flags 的数据初始化    uint16_t newBits = _flags & ~FAST_CACHE_ALLOC_MASK;    uint16_t sizeBits;    // Adding FAST_CACHE_ALLOC_DELTA16 allows for FAST_CACHE_ALLOC_MASK16    // to yield the proper 16byte aligned allocation size with a single mask    // 先通过 word_align 函数将传入的参数进行字节对齐    // 然后加上 FAST_CACHE_ALLOC_DELTA16 掩码,    // 这么做的目的是可以通过 FAST_CACHE_ALLOC_MASK16 使用单个掩码获取正确的以 16字节对齐内存布局大小    sizeBits = word_align(newSize) + FAST_CACHE_ALLOC_DELTA16;    // 最后位与 FAST_CACHE_ALLOC_MASK 掩码    sizeBits &= FAST_CACHE_ALLOC_MASK;    // 只有当传入的大小没有从保存的位数中溢出,才通过位或运算保存到 newBits。否则,newBits 中保存的是初始化的数据    if (newSize <= sizeBits) {        newBits |= sizeBits;    }    // 成员 _flags 保存处理好的数据    _flags = newBits;}

bytesForCapacity

获取指定缓存容量占用的字节大小

static size_t bytesForCapacity(uint32_t cap);size_t cache_t::bytesForCapacity(uint32_t cap) {    // fixme put end marker inline when capacity+1 malloc is inefficient    // 先获取结构体 bucket_t 占用的内存字节大小    // 再乘上传入的缓存容量 + 1 后的值    return sizeof(bucket_t) * (cap + 1);}

endMarker

获取缓存的结束标识

static struct bucket_t * endMarker(struct bucket_t *b, uint32_t cap);bucket_t *cache_t::endMarker(struct bucket_t *b, uint32_t cap) {    // bytesForCapacity() chooses whether the end marker is inline or not    // 先根据容量计算缓存占用的内存大小    // 再计算缓存指针内存地址加上占用的大小    // 最后 -1 就是缓存在内存中的结束地址    return (bucket_t *)((uintptr_t)b + bytesForCapacity(cap)) - 1;}

reallocate

重新生成缓存

void reallocate(mask_t oldCapacity, mask_t newCapacity, bool freeOld);ALWAYS_INLINEvoid cache_t::reallocate(mask_t oldCapacity, mask_t newCapacity, bool freeOld){    // 保存当前缓存容器    bucket_t *oldBuckets = buckets();    // 根据容量生成一个新缓存容器    bucket_t *newBuckets = allocateBuckets(newCapacity);    // Cache's old contents are not propagated.     // This is thought to save cache memory at the cost of extra cache fills.    // fixme re-measure this    ASSERT(newCapacity > 0);    ASSERT((uintptr_t)(mask_t)(newCapacity-1) == newCapacity-1);    // 用新的缓存容器和容量重置当前缓存    setBucketsAndMask(newBuckets, newCapacity - 1);        // 如果需要释放老缓存    if (freeOld) {        // 把老缓存添加到 garbage_refs 表中,以便稍后释放        cache_collect_free(oldBuckets, oldCapacity);    }}

insert

保存发送消息到缓存中

void insert(Class cls, SEL sel, IMP imp, id receiver);ALWAYS_INLINEvoid cache_t::insert(Class cls, SEL sel, IMP imp, id receiver){#if CONFIG_USE_CACHE_LOCK    cacheUpdateLock.assertLocked();#else    runtimeLock.assertLocked();#endif    ASSERT(sel != 0 && cls->isInitialized());    // Use the cache as-is if it is less than 3/4 full    // 缓存占用量 +1    mask_t newOccupied = occupied() + 1;    // 获取老的缓存容量    unsigned oldCapacity = capacity(), capacity = oldCapacity;    if (slowpath(isConstantEmptyCache())) {        // 如果当前缓存为空        // Cache is read-only. Replace it.        // 如果老容量也是空的,那么容量就设置为 4        if (!capacity) capacity = INIT_CACHE_SIZE;        // 调用 reallocate 函数重新生成容量为 4 的缓存        reallocate(oldCapacity, capacity, /* freeOld */false);    }    else if (fastpath(newOccupied <= capacity / 4 * 3)) {        // 如果新缓存占用量不足总容量的 3/4,就不作处理        // Cache is less than 3/4 full. Use it as-is.    }    else {        // 如果新缓存占用量超过了总容量的 3/4        // 如果老容量为空的,那么容量就设置为 4;否则,新容量扩充为之前的两倍        capacity = capacity ? capacity * 2 : INIT_CACHE_SIZE;        // 总容量大小不能超过 65536(即 2 的 256 次方)        if (capacity > MAX_CACHE_SIZE) {            capacity = MAX_CACHE_SIZE;        }        // 调用 reallocate 函数重新生成容量为 65536 的缓存        reallocate(oldCapacity, capacity, true);    }    // 获取缓存    bucket_t *b = buckets();    // 获取容量    mask_t m = capacity - 1;    // 根据方法名和容量生成一个哈希值    mask_t begin = cache_hash(sel, m);    mask_t i = begin;    // Scan for the first unused slot and insert there.    // There is guaranteed to be an empty slot because the    // minimum size is 4 and we resized at 3/4 full.    // 开始遍历,直到找到一个空的卡槽将消息相关数据插入    do {        // 如果缓存中哈希值 i 对应的是一个空的卡槽        if (fastpath(b[i].sel() == 0)) {            // 当前缓存使用量 +1            incrementOccupied();            // 将消息相关数据插入到哈希值 i 对应的位置            b[i].set<Atomic, Encoded>(sel, imp, cls);            // 跳出循环,并直接返回            return;        }        // 如果缓存中哈希值 i 对应的卡槽已经保存了该方法        if (b[i].sel() == sel) {            // The entry was added to the cache by some other thread            // before we grabbed the cacheUpdateLock.            // 也是跳出循环,并直接返回            return;        }        // 如果哈希值 i 对应的卡槽已经保存了其他方法,就查看哈希值(i + 1)对应的卡槽    } while (fastpath((i = cache_next(i, m)) != begin));    // 如果遍历完整个缓存的容量的每一个位置,都没能将方法插进去    // 就调用 bad_cache 函数打印日志,说明这个缓存有问题    cache_t::bad_cache(receiver, (SEL)sel, cls);}

bucket_t

modifierForSEL

获取方法签名修饰符

uintptr_t modifierForSEL(SEL newSel, Class cls) const {    // 将方法实现的地址、方法名地址和类地址进行位异或后返回    return (uintptr_t)&_imp ^ (uintptr_t)newSel ^ (uintptr_t)cls;}

encodeImp

对方法实现进行编码

uintptr_t encodeImp(IMP newImp, SEL newSel, Class cls) const {    // 如果没有方法实现直接返回零    if (!newImp) return 0;    // 将方法实现地址与类对象地址进行位异或运算后返回    return (uintptr_t)newImp ^ (uintptr_t)cls;}

sel

从 bucket_t 容器中获取方法名

// 调用元素 _sel 的 load 函数获取inline SEL sel() const { return _sel.load(memory_order::memory_order_relaxed); }

imp

从 bucket_t 容器中获取方法实现

inline IMP imp(Class cls) const {    // 调用元素 _imp 的 load 函数获取    uintptr_t imp = _imp.load(memory_order::memory_order_relaxed);    // 如果没有获取到返回空    if (!imp) return nil;    // 将获取到的值与类对象的地址进行位异或运算后返回    return (IMP)(imp ^ (uintptr_t)cls);}

set

向 bucket_t 容器中赋值

template <Atomicity, IMPEncoding>void set(SEL newSel, IMP newImp, Class cls);template<Atomicity atomicity, IMPEncoding impEncoding>void bucket_t::set(SEL newSel, IMP newImp, Class cls){    ASSERT(_sel.load(memory_order::memory_order_relaxed) == 0 ||           _sel.load(memory_order::memory_order_relaxed) == newSel);        // 是否需要编码方法实现    // 如果需要就调用 encodeImp 函数编码,否则就直接返回方法实现地址    uintptr_t newIMP = (impEncoding == Encoded                        ? encodeImp(newImp, newSel, cls)                        : (uintptr_t)newImp);    // 是否需要原子性操作    if (atomicity == Atomic) {        // 如果需要原子操作        // 调用元素 _imp 的 store 函数保存方法实现        _imp.store(newIMP, memory_order::memory_order_relaxed);                // 调用元素 _sel 的 load 函数获取方法名        if (_sel.load(memory_order::memory_order_relaxed) != newSel) {            // 如果方法名不同,则调用元素 _sel 的 store 函数保存方法名            _sel.store(newSel, memory_order::memory_order_release);        }    } else {        // 如果不需要原子操作        // 调用元素 _imp 的 store 函数保存方法实现        _imp.store(newIMP, memory_order::memory_order_relaxed);        // 调用元素 _sel 的 store 函数保存方法名        _sel.store(newSel, memory_order::memory_order_relaxed);    }}

class_data_bits_t

getBit

获取指定位的数据

bool getBit(uintptr_t bit) const{    // 通过位与运算获取 bits 中指定位数的数据    return bits & bit;}

setAndClearBits

设置和清空指定位的数据

void setAndClearBits(uintptr_t set, uintptr_t clear){    ASSERT((set & clear) == 0);    uintptr_t oldBits;    uintptr_t newBits;    // 开启循环,直到 bits 中的值被成功更新成 newBits    do {        // 原子操作获取原 bits 中的数据        oldBits = LoadExclusive(&bits);        // 先通过位或运算设置 bits 中指定位数的数据        // 再通过位取反运算获得要清空位        // 最后通过位与运算清空 bits 中指定位数的数据        newBits = (oldBits | set) & ~clear;    } while (!StoreReleaseExclusive(&bits, oldBits, newBits));}

setBits

设置指定位的数据

void setBits(uintptr_t set) {    // 通过位或运算设置 bits 中指定位数的数据    __c11_atomic_fetch_or((_Atomic(uintptr_t) *)&bits, set, __ATOMIC_RELAXED);}

clearBits

清空指定位的数据

void clearBits(uintptr_t clear) {    // 先通过位取反运算获得要清空位    // 再后通过位与运算清空 bits 中指定位数的数据    __c11_atomic_fetch_and((_Atomic(uintptr_t) *)&bits, ~clear, __ATOMIC_RELAXED);}

data

获取数据中 class_rw_t 类型对象地址

class_rw_t* data() const {    // 将 bits 与掩码 FAST_DATA_MASK 进行位与运算    // 获取保存在 bits 中 class_rw_t 类型对象地址    return (class_rw_t *)(bits & FAST_DATA_MASK);}

setData

设置数据中 class_rw_t 类型对象地址

void setData(class_rw_t *newData){    ASSERT(!data()  ||  (newData->flags & (RW_REALIZING | RW_FUTURE)));    // Set during realization or construction only. No locking needed.    // Use a store-release fence because there may be concurrent    // readers of data and data's contents.    // 先将 bits 与掩码 FAST_DATA_MASK 的反码进行位与运算,清空原数据    // 再与新数据进行位或运算,保存新数据    uintptr_t newBits = (bits & ~FAST_DATA_MASK) | (uintptr_t)newData;    // 建立非原子和宽松原子访问的内存同步排序    atomic_thread_fence(memory_order_release);    // 保存新数据    bits = newBits;}

safe_ro

获取数据中 class_ro_t 类型对象地址

const class_ro_t *safe_ro() {    // 获取数据中 class_rw_t 对象    class_rw_t *maybe_rw = data();    if (maybe_rw->flags & RW_REALIZED) {        // 如果类已经实现        // maybe_rw is rw        // 返回 class_rw_t 对象的 ro 元素        return maybe_rw->ro;    } else {        // maybe_rw is actually ro        // 如果类没实现        // 直接返回 class_rw_t 对象        return (class_ro_t *)maybe_rw;    }}
  • 这个方法说明,如果类还没实现,通过 data() 获取到的是 class_ro_t 类型的数据
  • 如果类已经实现,通过 data() 获取到的是 class_rw_t 类型的数据,而 class_ro_t 类型的数据保存在其 ro 元素中

isAnySwift

是否为 swift 类型的数据

bool isAnySwift() {    // 只要是新版 swift 类或老版 swift 类二者之一就可以    return isSwiftStable() || isSwiftLegacy();}

isSwiftStable

是否是来自新版稳定 Swift ABI 的 Swift 类

bool isSwiftStable() {    // 根据成员 bits 中掩码 FAST_IS_SWIFT_STABLE 储存的数据判断    return getBit(FAST_IS_SWIFT_STABLE);}

setIsSwiftStable

设置标识当前数据为自新版稳定 Swift ABI 的 Swift 类

void setIsSwiftStable() {    // 设置成员 bits 中掩码 FAST_IS_SWIFT_STABLE 的数据    // 并且清除掩码 FAST_IS_SWIFT_LEGACY 中存储的数据    setAndClearBits(FAST_IS_SWIFT_STABLE, FAST_IS_SWIFT_LEGACY);}

isSwiftLegacy

是否是来自老版稳定 Swift ABI 的 Swift 类

bool isSwiftLegacy() {    // 根据成员 bits 中掩码 FAST_IS_SWIFT_LEGACY 储存的数据判断    return getBit(FAST_IS_SWIFT_LEGACY);}

setIsSwiftLegacy

设置标识当前数据为自老版稳定 Swift ABI 的 Swift 类

void setIsSwiftLegacy() {    // 设置成员 bits 中掩码 FAST_IS_SWIFT_LEGACY 的数据    // 并且清除掩码 FAST_IS_SWIFT_STABLE 中存储的数据    setAndClearBits(FAST_IS_SWIFT_LEGACY, FAST_IS_SWIFT_STABLE);}

isSwiftStable_ButAllowLegacyForNow

是否是稳定的 Swift ABI 的 Swift 类

bool isSwiftStable_ButAllowLegacyForNow() {    // 调用 isAnySwift 判断    return isAnySwift();}

swiftMetadataInitializer

获取 swift 类元数据初始化器

_objc_swiftMetadataInitializer swiftMetadataInitializer() {    // This function is called on un-realized classes without    // holding any locks.    // Beware of races with other realizers.    // 调用 class_ro_t 的 swiftMetadataInitializer 函数获取    return safe_ro()->swiftMetadataInitializer();}

class_rw_t

setFlags

设置指定标志位数据

void setFlags(uint32_t set) {    // 原子性的设置成员 flags 中指定位的数据    __c11_atomic_fetch_or((_Atomic(uint32_t) *)&flags, set, __ATOMIC_RELAXED);}

clearFlags

清空指定标志位数据

void clearFlags(uint32_t clear) {    // 原子性的清空成员 flags 中指定位的数据    __c11_atomic_fetch_and((_Atomic(uint32_t) *)&flags, ~clear, __ATOMIC_RELAXED);}

changeFlags

设置并清空指定标志位数据

void changeFlags(uint32_t set, uint32_t clear) {    // 要设置和要清空的不能为相同的位    ASSERT((set & clear) == 0);    uint32_t oldf, newf;    // 开启循环,直到 flags 中的值被成功更新为 newf    do {        oldf = flags;        // 先通过位或运算设置 oldf 中指定位数的数据        // 再通过位取反运算获得要清空位        // 最后通过位与运算清空 oldf 中指定位数的数据        newf = (oldf | set) & ~clear;    } while (!OSAtomicCompareAndSwap32Barrier(oldf, newf, (volatile int32_t *)&flags));}

class_ro_t

swiftMetadataInitializer

获取 swift 类元数据初始化器

_objc_swiftMetadataInitializer __ptrauth_objc_method_list_imp _swiftMetadataInitializer_NEVER_USE[0];_objc_swiftMetadataInitializer swiftMetadataInitializer() const {    if (flags & RO_HAS_SWIFT_INITIALIZER) {        // 如果设置了 RO_HAS_SWIFT_INITIALIZER 掩码位的数据        // 返回 _objc_swiftMetadataInitializer 类型的函数指针        return _swiftMetadataInitializer_NEVER_USE[0];    } else {        // 否则返回空        return nil;    }}

baseMethods

获取编译时产生的方法列表

method_list_t *baseMethods() const {    // 直接返回成员 baseMethodList    return baseMethodList;}

duplicate

复制当前 ro 数据

class_ro_t *duplicate() const {    if (flags & RO_HAS_SWIFT_INITIALIZER) {        // 如果类具有用于 swift 元数据初始化程序回调的 ro 字段        // 内存大小是当前数据占用大小 + _objc_swiftMetadataInitializer 类型的函数指针大小        size_t size = sizeof(*this) + sizeof(_swiftMetadataInitializer_NEVER_USE[0]);        // 申请内存保存当前数据的副本        class_ro_t *ro = (class_ro_t *)memdup(this, size);        // 设置副本的 swift 类元数据初始化器        ro->_swiftMetadataInitializer_NEVER_USE[0] = this->_swiftMetadataInitializer_NEVER_USE[0];        // 返回副本        return ro;    } else {        // 否则        // 内存大小就是当前 ro 数据的大小        size_t size = sizeof(*this);        // 申请内存保存当前数据的副本        class_ro_t *ro = (class_ro_t *)memdup(this, size);        // 返回副本        return ro;    }}

category_t

methodsForMeta

获取类方法或者实例方法

method_list_t *methodsForMeta(bool isMeta) {    // 如果要获取类方法,返回成员 classMethods 中的数据    if (isMeta) return classMethods;    // 如果要获取实例方法,返回成员 instanceMethods 的数据    else return instanceMethods;}

propertiesForMeta

获取类属性或者实例属性

property_list_t *propertiesForMeta(bool isMeta, struct header_info *hi);property_list_t *category_t::propertiesForMeta(bool isMeta, struct header_info *hi){    // 如果要获取实例属性,返回成员 instanceProperties 中的数据    if (!isMeta) return instanceProperties;    // 如果要获取类属性,先通过头信息 hi 判断是否类属性,如果有的话,返回成员 _classProperties 中的数据    else if (hi->info()->hasCategoryClassProperties()) return _classProperties;    // 否则就是没有类属性    else return nil;}

protocolsForMeta

获取类协议或者实例协议

protocol_list_t *protocolsForMeta(bool isMeta) {    // 没有类协议    if (isMeta) return nullptr;    // 如果要获取实例协议,返回成员 protocols 中的数据    else return protocols;}
.
.

广告 广告

评论区