iOS底层剖析 objc_class结构

2019-07-22  本文已影响0人  困惑的柴火

iOS中不管类对象还是元类对象类型都是Class,而Class的结构则是objc_class结构体

typedef struct objc_class *Class;

1.OBJC1 objc_class结构(过时)

头文件 #import <objc/runtime.h>内看到的objc_class结构为:


struct objc_class {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;  //isa指针
    
#if !__OBJC2__
    Class _Nullable super_class                              OBJC2_UNAVAILABLE; //父类
    const char * _Nonnull name                               OBJC2_UNAVAILABLE;     //名字
    long version                                             OBJC2_UNAVAILABLE;
        //版本号
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list * _Nullable ivars                  OBJC2_UNAVAILABLE;     //属性列表
    struct objc_method_list * _Nullable * _Nullable methodLists                    OBJC2_UNAVAILABLE;       //方法列表
    struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE;     //
    struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE;     //协议列表
#endif
    
} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */

2.OBJC2 objc_class结构

可以在https://opensource.apple.com/source/objc4/objc4-723/中下载和查看开源的最新版本的Runtime库源代码。Runtime库的源代码是用汇编和C++混合实现的,你可以在头文件objc-runtime-new.h中看到关于struct objc_class结构的详细定义。
查看代码你会发现,objc_class继承自objc_object,在头文件objc-private.h中看到关于objc_object结构的详细定义。
因为这是通过c++实现的,所以结构体内会包含函数。
objc_class的结构体内的data反回了一个class_rw_t的结构体指针,而这个指针的结构是:


struct class_rw_t {
    uint32_t flags;
    uint32_t version;

    const class_ro_t *ro;

    method_array_t methods;
    property_array_t properties;
    protocol_array_t protocols;

    Class firstSubclass;
    Class nextSiblingClass;

    char *demangledName;

    void setFlags(uint32_t set) 
    {
        OSAtomicOr32Barrier(set, &flags);
    }

    void clearFlags(uint32_t clear) 
    {
        OSAtomicXor32Barrier(clear, &flags);
    }

    // set and clear must not overlap
    void changeFlags(uint32_t set, uint32_t clear) 
    {
        assert((set & clear) == 0);

        uint32_t oldf, newf;
        do {
            oldf = flags;
            newf = (oldf | set) & ~clear;
        } while (!OSAtomicCompareAndSwap32Barrier(oldf, newf, (volatile int32_t *)&flags));
    }
};

而class_rw_t是通过bits调用data方法得来的,我们来到data方法内部实现。我们可以看到,data函数内部仅仅对bits进行&FAST_DATA_MASK操作

class_rw_t* data() {
        return (class_rw_t *)(bits & FAST_DATA_MASK);
    }

成员变量信息则是存储在class_ro_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;

    method_list_t *baseMethods() const {
        return baseMethodList;
    }
};

class_rw_t 表示read write,class_ro_t 表示 read only。

通过以上分析可以得到objc_class的结构类图:

image
图片最左边显示的内容有一个编辑错误,不应该是NSObject而应该是objc_class。

文章引用链接:
1.https://www.jianshu.com/p/df6629ec9a25
2.https://www.jianshu.com/p/4f732bd01f27
文章2有证明过程,这里不再赘述

上一篇 下一篇

猜你喜欢

热点阅读