iOS开发之runtime(6):初识class_rw_t

logo

本系列博客是本人的源码阅读笔记,如果有 iOS 开发者在看 runtime 的,欢迎大家多多交流。为了方便讨论,本人新建了一个微信群(iOS技术讨论群),想要加入的,请添加本人微信:zhujinhui207407,【加我前请备注:ios 】,本人博客http://www.kyson.cn 也在不停的更新中,欢迎一起讨论

本文完整版详见笔者小专栏:https://xiaozhuanlan.com/runtime

背景

上一篇文章中我们了解到hasDefaultAWZ()setHasDefaultAWZ ()data()flag,而data()返回的其实是一个名为class_rw_t的结构体。

class_rw_t* data() {
    return (class_rw_t *)(bits & FAST_DATA_MASK);
}
void setData(class_rw_t *newData)
{
    assert(!data()  ||  (newData->flags & (RW_REALIZING | RW_FUTURE)));
    bits = (bits & ~FAST_DATA_MASK) | (uintptr_t)newData;
}

bool hasDefaultAWZ() {
    return data()->flags & RW_HAS_DEFAULT_AWZ;
}
void setHasDefaultAWZ() {
    data()->setFlags(RW_HAS_DEFAULT_AWZ);
}
void setHasCustomAWZ() {
    data()->clearFlags(RW_HAS_DEFAULT_AWZ);
}

我们先来分析一下data()函数吧:

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

FAST_DATA_MASK的定义

#define FAST_DATA_MASK          0x00007ffffffffff8UL

转换成二进制如下:


可以推断,class_rw_t是由class_data_bits_t中的bits第3位到46位存储的。接下来我们好好讲一下class_rw_t这个结构体。

class_rw_t
class_rw_t 提供了运行时对类拓展的能力,存有类的方法、属性(成员变量)、协议等信息。class_rw_t 的内容是可以在运行时被动态修改的,可以说运行时对类的拓展大都是存储在这里的。

这里先对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);
    }

    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
存储了类的属性列表property_array_t properties;,其中property_array_t定义如下:

class property_array_t : 
    public list_array_tt 
{
    typedef list_array_tt Super;

 public:
    property_array_t duplicate() {
        return Super::duplicate();
    }
};

存储了类的方法列表method_array_t methods;,类似的,其中method_array_t定义如下:

class method_array_t : 
    public list_array_tt 
{
    typedef list_array_tt Super;

 public:
    method_list_t **beginCategoryMethodLists() {
        return beginLists();
    }
    
    method_list_t **endCategoryMethodLists(Class cls);

    method_array_t duplicate() {
        return Super::duplicate();
    }
};

存储了类的协议列表protocol_array_t protocols;,仍然,protocol_array_t的定义如下:

class protocol_array_t : 
    public list_array_tt 
{
    typedef list_array_tt Super;

 public:
    protocol_array_t duplicate() {
        return Super::duplicate();
    }
};

不了解的结构体:const class_ro_t *ro;,不过看其属性以及成员,像极了class_rw_t

struct class_ro_t {
    uint32_t flags;
    uint32_t instanceStart;
    uint32_t instanceSize;
    uint32_t reserved;
    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_ro_t做个大概介绍:

class_ro_t
class_ro_t 存储的大多是类在编译时就已经确定的信息。(区别于class_rw_t, 提供了运行时对类拓展的能力)。

总结

本文对class_rw_t做个简单的介绍,让大家对其有个初步印象,后序的文章会带大家更深的了解这个重要的结构体。


本文完整版详见笔者小专栏:https://xiaozhuanlan.com/runtime


广告

我的首款个人开发的APP壁纸宝贝上线了,欢迎大家下载。

壁纸宝贝

你可能感兴趣的:(iOS开发之runtime(6):初识class_rw_t)