本系列博客是本人的源码阅读笔记,如果有 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壁纸宝贝上线了,欢迎大家下载。