背景
上一篇文章中我们了解到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<property_t, property_list_t>
{
typedef list_array_tt<property_t, property_list_t> Super;
public:
property_array_t duplicate() {
return Super::duplicate<property_array_t>();
}
};
存储了类的方法列表method_array_t methods;,类似的,其中method_array_t定义如下:
class method_array_t :
public list_array_tt<method_t, method_list_t>
{
typedef list_array_tt<method_t, method_list_t> Super;
public:
method_list_t **beginCategoryMethodLists() {
return beginLists();
}
method_list_t **endCategoryMethodLists(Class cls);
method_array_t duplicate() {
return Super::duplicate<method_array_t>();
}
};
存储了类的协议列表protocol_array_t protocols;,仍然,protocol_array_t的定义如下:
class protocol_array_t :
public list_array_tt<protocol_ref_t, protocol_list_t>
{
typedef list_array_tt<protocol_ref_t, protocol_list_t> Super;
public:
protocol_array_t duplicate() {
return Super::duplicate<protocol_array_t>();
}
};
不了解的结构体: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做个简单的介绍,让大家对其有个初步印象,后序的文章会带大家更深的了解这个重要的结构体。