Runtime備忘-資料結構

小星星_ios發表於2020-03-22

基於objc-runtime-new分析,老版的就先不記錄了

typedef struct objc_class *Class;
struct objc_object {
    Class isa;
}
struct objc_class: objc_object {
    Class superclass;
    cache_t cache;
    class_data_bits_t bits; // typedef unsigned long uintptr_t;這個就是讓系統分配64個位元組的記憶體給 isa 用而已
}
struct cache_t {
    struct bucket_t *_buckets; // 快取方法的雜湊表
    mask_t _mask; // typedef uint32_t mask_t; 雜湊表長度 - 1
    mask_t _occupied; // 已經佔用的數量
}
struct bucket_t {
    MethodCacheIMP _imp; // using MethodCacheIMP = IMP;
    cache_key_t _key; // typedef uintptr_t cache_key_t;
}
union isa_t {
    isa_t() { }
    isa_t(uintptr_t value) : bits(value) { }
    Class cls;
    uintptr_t bits;
    struct {
        ISA_BITFIELD;
    }
}
struct class_rw_t {
    const class_ro_t *ro;
    method_array_t methods;
    property_array_t properties;
    protocol_array_t protocols;
}
class class_ro_t {
    const char * name;
    method_list_t * baseMethodList;
    protocol_list_t * baseProtocols;
    const ivar_list_t * ivars;
    const uint8_t * weakIvarLayout;
    property_list_t *baseProperties;
}
struct method_t {
    SEL name;
    const char *type; // types包含了函式返回值,引數編碼的字串
    MethodListIMP imp;
    struct SortBySELAddress
}
複製程式碼

FAST_DATA_MASK 的值是 0x00007ffffffffff8UL bits 和 FAST_DATA_MASK 按位與,實際上就是取了 bits 中的[3,46]位 objc_msgSend第一次傳送訊息會觸發方法查詢,找到方法後會呼叫cache_fill()方法把方法快取到cache中 通過將@selector(key) & mask = index之後,bucket_t->set(key, imp) 最小的 buckets大小是4

= 3/4,擴容為兩倍

相關文章