前面已经忘记看了多少天了,终于把
objc_object和objc_class的相关的数据结构都看完了,现在只剩下objc_class中定义的函数没有分析,那么就由本篇开始分析吧!⛽️⛽️
objc_class 函数列表
class_rw_t *data() const
data 函数是直接调用的 class_data_bits_t bits 的 data 函数,内部实现的话也很简单,通过掩码 #define FAST_DATA_MASK 0x00007ffffffffff8UL(二进制第 3-46 位是 1,其他位都是 0) 从 class_data_bits_t bits 的 uintptr_t bits(uintptr_t bits 是 struct class_data_bits_t 仅有的一个成员变量)中取得 class_rw_t 指针。
class_rw_t *data() const {
return bits.data();
}
// class_data_bits_t 中:
class_rw_t* data() const {
return (class_rw_t *)(bits & FAST_DATA_MASK);
}
void setData(class_rw_t *newData)
同样 setData 函数调用的也是 class_data_bits_t bits 的 setData 函数,在 struct class_data_bits_t 的 setData 函数中, uintptr_t bits 首先和 ~FAST_DATA_MASK 做与操作把掩码位置为 0,其它位保持不变,然后再和 newData 做或操作,把 newData 中值为 1 的位也设置到 uintptr_t bits 中。
void setData(class_rw_t *newData) {
bits.setData(newData);
}
void setInfo(uint32_t set)
setInfo 函数调用的是 class_rw_t 的 setFlags 函数,通过原子的或操作把 set 中值为 1 的位也设置到 class_rw_t 的 uint32_t flags 中。(flags 和 set 都是 uint32_t 类型,都是 32 位。)
void setInfo(uint32_t set) {
ASSERT(isFuture() || isRealized());
data()->setFlags(set);
}
void clearInfo(uint32_t clear)
clearInfo 函数调用的是 class_rw_t 的 clearFlags 函数,通过原子的与操作把 ~clear 中值为 0 的位也设置到 class_rw_t 的 uint32_t flags 中。(flags 和 clear 都是 uint32_t 类型,都是 32 位。)
void clearInfo(uint32_t clear) {
ASSERT(isFuture() || isRealized());
data()->clearFlags(clear);
}
void changeInfo(uint32_t set, uint32_t clear)
changeInfo 函数调用的同样也是 class_rw_t 的 changeFlags 函数,先取得 class_rw_t 的 uint32_t flags 赋值到一个临时变量 uint32_t oldf 中,然后 oldf 和 uint32_t set 做一个或操作,把 set 值为 1 的位也都设置到 oldf 中,然后再和 ~clear 做与操作,把 ~clear 中是 0 的位也都设置其中,并把 !OSAtomicCompareAndSwap32Barrier(oldf, newf, (volatile int32_t *)&flags) 作为 do while 循环的循环条件,保证 uint32_t oldf 的值都能写入 uint32_t flags 中。
// set and clear must not overlap
void changeInfo(uint32_t set, uint32_t clear) {
ASSERT(isFuture() || isRealized());
ASSERT((set & clear) == 0);
data()->changeFlags(set, clear);
}
FAST_HAS_DEFAULT_RR/RW_HAS_DEFAULT_RR
FAST_HAS_DEFAULT_RR 用以在 __LP64__ 平台下判断 objc_class 的 class_data_bits_t bits 第二位的值是否为 1,以此表示该类或者父类是否有如下函数的默认实现。对应在 非 __LP64 平台下,则是使用 RW_HAS_DEFAULT_RR,且判断的位置发生了变化,RW_HAS_DEFAULT_RR 用以判断从 objc_class 的 class_data_bits_t bits 中取的得 class_rw_t 指针指向的 class_rw_t 实例的 uint32_t flags 的第 14 位的值是否为 1,以此表示该类或者父类是否有如下函数的默认实现:
retain/release/autorelease/retainCount_tryRetain/_isDeallocating/retainWeakReference/allowsWeakReference
// Values for class_rw_t->flags (RW_*), cache_t->_flags (FAST_CACHE_*),
// or class_t->bits (FAST_*).
// 当从 class_rw_t->flags 取值时,使用 RW_* 做前缀,
// 当从 cache_t->_flags 取值时,使用 FAST_CACHE_* 做前缀,
// 当从 class_data_bits_t->bits 取值时,使用 FAST_* 做前缀。
// FAST_* and FAST_CACHE_* are stored on the class,
// reducing pointer indirection.
// FAST_* 和 FAST_CACHE_* 前缀开头的值,
// 分别保存在 objc_class 的 class_data_bits_t bits 和 cache_t cache 两个成员变量中,直接减少了指针间接寻值,
// RW_* 前缀开头的值首先要从 class_data_bits_t bits 中找到 class_rw_t 的指针,然后根据指针再去寻 class_rw_t 的值。
#if __LP64__
...
// class or superclass has default retain/release/autorelease/retainCount/
// _tryRetain/_isDeallocating/retainWeakReference/allowsWeakReference
// 类或者其父类
// 在 class_data_bits_t bits 的 uintptr_t bits 中判断。
#define FAST_HAS_DEFAULT_RR (1UL<<2)
...
#else
...
// class or superclass has default retain/release/autorelease/retainCount/
// _tryRetain/_isDeallocating/retainWeakReference/allowsWeakReference
// 类或者父类
// 在 class_rw_t 的 uint32_t flags 中判断。
#define RW_HAS_DEFAULT_RR (1<<14)
...
#endif
hasCustomRR/setHasDefaultRR/setHasCustomRR
在__LP64__ 平台和其它平台下的判断、设置、清除 objc_class 的默认 RR 函数的标记位。
#if FAST_HAS_DEFAULT_RR
// 直接判断 class_data_bits_t bits 的 uintptr_t bits 二进制表示的第 2 位的值是否为 1。
bool hasCustomRR() const {
return !bits.getBit(FAST_HAS_DEFAULT_RR);
}
// 以原子方式把 class_data_bits_t bits 的 uintptr_t bits 二进制表示的第 2 位设置为 1。
void setHasDefaultRR() {
bits.setBits(FAST_HAS_DEFAULT_RR);
}
// Default 和 Custom 是相反的,如果 objc_class 有 CustomRR 则没有 DefaultRR。
// 以原子方式把 class_data_bits_t bits 的 uintptr_t bits 二进制表示的第 2 位设置为 0,
// 表示 objc_class 有自定义的 RR 函数,
// 即 objc_class 的 RR 函数已经被重载了。
void setHasCustomRR() {
bits.clearBits(FAST_HAS_DEFAULT_RR);
}
#else
// 直接判断 class_rw_t 的 flags 二进制表示的第 14 位的值是否为 1。
bool hasCustomRR() const {
return !(bits.data()->flags & RW_HAS_DEFAULT_RR);
}
// 以原子方式把 class_rw_t 的 uint32_t flags 二进制表示的第 14 位设置为 1。
void setHasDefaultRR() {
bits.data()->setFlags(RW_HAS_DEFAULT_RR);
}
// Default 和 Custom 是相反的,如果 objc_class 有 CustomRR 则没有 DefaultRR。
// 以原子方式把 class_rw_t 的 uint32_t flags 二进制表示的第 14 位设置为 0,
// 表示 objc_class 有自定义的 RR 函数,
// 即 objc_class 的 RR 函数已经被重载了。
void setHasCustomRR() {
bits.data()->clearFlags(RW_HAS_DEFAULT_RR);
}
#endif
FAST_CACHE_HAS_DEFAULT_AWZ/RW_HAS_DEFAULT_AWZ
FAST_CACHE_HAS_DEFAULT_AWZ 用以在 __LP64__ 平台下判断 objc_class 的 cache_t cache 的 uint16_t _flags 二进制表示时第 14 位的值是否为 1,以此表示该类或者父类是否有 alloc/allocWithZone 函数的默认实现。(注意,这里和上面的 RR 不同,RR 是一组实例方法保存在类中,而 alloc/allocWithZone 是一组类方法保存在元类中。)而在 非 __LP64__ 平台下,则是使用 RW_HAS_DEFAULT_AWZ,且判断的位置发生了变化,RW_HAS_DEFAULT_AWZ 用以判断从 objc_class 的 class_data_bits_t bits 中取得的 class_rw_t 指针指向的 class_rw_t 实例的 uint32_t flags 的第 16 位的值是否为 1,以此表示该类或者父类是否有 alloc/allocWithZone 函数的默认实现。
// Values for class_rw_t->flags (RW_*), cache_t->_flags (FAST_CACHE_*),
// or class_t->bits (FAST_*).
// 当从 class_rw_t->flags 取值时,使用 RW_* 做前缀,
// 当从 cache_t->_flags 取值时,使用 FAST_CACHE_* 做前缀,
// 当从 class_data_bits_t->bits 取值时,使用 FAST_* 做前缀
// FAST_* and FAST_CACHE_* are stored on the class,
// reducing pointer indirection.
// FAST_* 和 FAST_CACHE_* 前缀开头的值分别保存在
// objc_class 的 class_data_bits_t bits 和 cache_t cache 两个成员变量中,
// 直接减少了指针间接寻值,
// RW_* 前缀开头的值首先要从 class_data_bits_t bits 中找到 class_rw_t 的指针,
// 然后根据指针再去寻值。
#if __LP64__
...
// class or superclass has default alloc/allocWithZone: implementation.
// 类或父类有默认的 alloc/allocWithZone: 函数实现。
// Note this is is stored in the metaclass.
// 注意,alloc/allocWithZone: 都是类方法,它们都是保存在元类中的。
#define FAST_CACHE_HAS_DEFAULT_AWZ (1<<14)
...
#else
...
// class or superclass has default alloc/allocWithZone: implementation.
// 类或父类有默认的 alloc/allocWithZone: 函数实现。
// Note this is is stored in the metaclass.
// 注意,alloc/allocWithZone: 都是类方法,它们都是保存在元类中的。
#define RW_HAS_DEFAULT_AWZ (1<<16)
...
#endif
hasCustomAWZ/setHasDefaultAWZ/setHasDefaultAWZ
在 __LP64__ 平台和其它平台下判断、设置、清除 objc_class 的默认 AWZ 函数的标记位。
#if FAST_CACHE_HAS_DEFAULT_AWZ
// 直接判断 cache_t cache 的 uint16_t _flags 二进制表示的第 14 位的值是否为 1。
bool hasCustomAWZ() const {
return !cache.getBit(FAST_CACHE_HAS_DEFAULT_AWZ);
}
// 以原子方式把 cache_t cahce 的 uint16_t _flags 二进制表示的第 14 位设置为 1。
void setHasDefaultAWZ() {
cache.setBit(FAST_CACHE_HAS_DEFAULT_AWZ);
}
// Default 和 Custom 是相反的,如果 objc_class 有 CustomAWZ 则没有 DefaultAWZ。
// 以原子方式把 cache_t cache 的 uint16_t _flags 二进制表示的第 14 位设置为 0,
// 表示 objc_class 有自定义的 alloc/allocWithZone: 函数,
// 即 objc_class 的 alloc/allocWithZone: 函数已经被重载了。
void setHasCustomAWZ() {
cache.clearBit(FAST_CACHE_HAS_DEFAULT_AWZ);
}
#else
// 直接判断 class_rw_t 的 flags 二进制表示的第 16 位的值是否为 1。
bool hasCustomAWZ() const {
return !(bits.data()->flags & RW_HAS_DEFAULT_AWZ);
}
// 以原子方式把 class_rw_t 的 uint32_t flags 二进制表示的第 16 位设置为 1。
void setHasDefaultAWZ() {
bits.data()->setFlags(RW_HAS_DEFAULT_AWZ);
}
// Default 和 Custom 是相反的,如果 objc_class 有 CustomAWZ 则没有 DefaultAWZ。
// 以原子方式把 class_rw_t 的 uint32_t flags 二进制表示的第 16 位设置为 0,
// 表示 objc_class 有自定义的 alloc/allocWithZone: 函数,
// 即 objc_class 的 alloc/allocWithZone: 函数已经被重载了。
void setHasCustomAWZ() {
bits.data()->clearFlags(RW_HAS_DEFAULT_AWZ);
}
#endif
FAST_CACHE_HAS_DEFAULT_CORE/RW_HAS_DEFAULT_CORE
FAST_CACHE_HAS_DEFAULT_CORE 用以在 __LP64__ 平台下判断 objc_class 的 cache_t cache 的 uint16_t _flags 二进制表示时第 15 位的值是否为 1,以此表示该类或者父类是否有 new/self/class/respondsToSelector/isKindOfClass 函数的默认实现。而在 非 __LP64__ 平台下,则是使用 RW_HAS_DEFAULT_CORE,且判断的位置发生了变化,RW_HAS_DEFAULT_CORE 用以判断从 objc_class 的 class_data_bits_t bits 中取得 class_rw_t 指针指向的 class_rw_t 实例的 uint32_t flags 的第 13 位的值是否为 1,以此表示该类或者父类是否有 new/self/class/respondsToSelector/isKindOfClass 函数的默认实现。
#if __LP64__
...
// class or superclass has default new/self/class/respondsToSelector/isKindOfClass
// 类或者父类有默认的 new/self/class/respondsToSelector/isKindOfClass
#define FAST_CACHE_HAS_DEFAULT_CORE (1<<15)
...
#else
...
// class or superclass has default new/self/class/respondsToSelector/isKindOfClass
// 类或者父类有默认的 new/self/class/respondsToSelector/isKindOfClass
#define RW_HAS_DEFAULT_CORE (1<<13)
...
#endif
hasCustomCore/setHasDefaultCore/setHasCustomCore
在 __LP64__ 平台和其它平台下判断、设置、清除 objc_class 的默认 Core 函数的标记位。
#if FAST_CACHE_HAS_DEFAULT_CORE
// 直接判断 cache_t cache 的 uint16_t _flags 二进制表示的第 15 位的值是否为 1。
bool hasCustomCore() const {
return !cache.getBit(FAST_CACHE_HAS_DEFAULT_CORE);
}
// 以原子方式把 cache_t cache 的 uint16_t _flags 二进制表示的第 15 位设置为 1。
void setHasDefaultCore() {
return cache.setBit(FAST_CACHE_HAS_DEFAULT_CORE);
}
// Default 和 Custom 是相反的,如果 objc_calss 有 CustomCore 则没有 DefaultCore。
// 以原子方式把 cache_t cache 的 uint16_t _flags 二进制表示的第 15 位设置为 0,
// 表示 objc_calss 有自定义的 new/self/class/respondsToSelector/isKindOfClass 函数,
// 即 objc_class 的 new/self/class/respondsToSelector/isKindOfClass 函数已经被重载了。
void setHasCustomCore() {
return cache.clearBit(FAST_CACHE_HAS_DEFAULT_CORE);
}
#else
// 直接判断 class_rw_t 的 uint32_t flags 二进制表示的第 13 位的值是否为 1。
bool hasCustomCore() const {
return !(bits.data()->flags & RW_HAS_DEFAULT_CORE);
}
// 以原子方式把 class_rw_t 的 uint32_t flags 二进制表示的第 13 位设置为 1。
void setHasDefaultCore() {
bits.data()->setFlags(RW_HAS_DEFAULT_CORE);
}
// Default 和 Custom 是相反的,如果 objc_class 有 CustomCore 则没有 DefaultCore。
// 以原子方式把 class_rw_t 的 uint32_t flags 二进制表示的第 13 位设置为 0,
// 表示 objc_class 有自定义的 new/self/class/respondsToSelector/isKindOfClass 函数,
// 即 objc_class 的 new/self/class/respondsToSelector/isKindOfClass 函数已经被重载了。
void setHasCustomCore() {
bits.data()->clearFlags(RW_HAS_DEFAULT_CORE);
}
#endif
FAST_CACHE_HAS_CXX_CTOR/RW_HAS_CXX_CTOR/FAST_CACHE_HAS_CXX_DTOR/RW_HAS_CXX_DTOR
FAST_CACHE_HAS_CXX_CTOR 用以在 __LP64__ 平台下判断 objc_class 的 cache_t cache 的 uint16_t _flags 二进制表示时第 1 位的值是否为 1,以此表示该类或者父类是否有 .cxx_construct 函数实现。而在 非 __LP64__ 平台下,则是使用 RW_HAS_CXX_CTOR,且判断的位置发生了变化,RW_HAS_CXX_CTOR 用以判断从 objc_class 的 class_data_bits_t bits 中取得 class_rw_t 指针指向的 class_rw_t 实例的 uint32_t flags 的第 18 位的值是否为 1,以此表示该类或者父类是否有 .cxx_construct 函数实现。对应的 FAST_CACHE_HAS_CXX_DTOR 和 RW_HAS_CXX_DTOR 表示该类或者父类是否有 .cxx_destruct 函数实现。
这里需要注意的是在 __LP64__ && __arm64__ 平台下 FAST_CACHE_HAS_CXX_DTOR 是 1<<0,而在 __LP64__ && !__arm64__ 平台下 FAST_CACHE_HAS_CXX_DTOR 是 1<<2。
#if __LP64__
...
#if __arm64__
// class or superclass has .cxx_construct/.cxx_destruct implementation。
// 类或者父类有 .cxx_construct/.cxx_destruct 函数实现。
// FAST_CACHE_HAS_CXX_DTOR is the first bit so that setting
// it in isa_t::has_cxx_dtor is a single bfi.
// FAST_CACHE_HAS_CXX_DTOR 是第一位,
// 因此在 isa_t::has_cxx_dtor 中进行设置仅是一个位字段。
// uintptr_t has_cxx_dtor : 1;
// __LP64__ && __arm64__ 平台下
#define FAST_CACHE_HAS_CXX_DTOR (1<<0)
#define FAST_CACHE_HAS_CXX_CTOR (1<<1)
...
#else
...
// class or superclass has .cxx_construct/.cxx_destruct implementation.
// 类或者父类有 .cxx_construct/.cxx_destruct 函数实现。
// FAST_CACHE_HAS_CXX_DTOR is chosen to alias with isa_t::has_cxx_dtor.
// 选择 FAST_CACHE_HAS_CXX_DTOR 作为 isa_t::has_cxx_dtor 的别名。
// __LP64__ && !__arm64__ 平台下
#define FAST_CACHE_HAS_CXX_CTOR (1<<1)
#define FAST_CACHE_HAS_CXX_DTOR (1<<2)
#endif
...
#else
...
// class or superclass has .cxx_construct implementation.
// 类或者父类有 .cxx_construct 函数实现。
#define RW_HAS_CXX_CTOR (1<<18)
// class or superclass has .cxx_destruct implementation
// 类或者父类有 .cxx_destruct 函数实现。
#define RW_HAS_CXX_DTOR (1<<17)
...
#endif
hasCxxCtor/setHasCxxCtor/hasCxxDtor/setHasCxxDtor
在 __LP64__ 平台和其它平台下判断、设置(注意这里没有清除)objc_class 的 .cxx_construct/.cxx_destruct 函数实现的标记位。
#if FAST_CACHE_HAS_CXX_CTOR
// 直接判断 cache_t cache 的 uint16_t _flags 二进制表示的第 1 位的值是否为 1。
bool hasCxxCtor() {
ASSERT(isRealized());
return cache.getBit(FAST_CACHE_HAS_CXX_CTOR);
}
// 以原子方式把 cache_t cache 的 uint16_t _flags 二进制表示的第 1 位设置为 1。
void setHasCxxCtor() {
cache.setBit(FAST_CACHE_HAS_CXX_CTOR);
}
#else
// 直接判断 class_rw_t 的 flags 二进制表示的第 18 位的值是否为 1。
bool hasCxxCtor() {
ASSERT(isRealized());
return bits.data()->flags & RW_HAS_CXX_CTOR;
}
// 以原子方式把 class_rw_t 的 uint32_t flags 二进制表示的第 18 位设置为 1。
void setHasCxxCtor() {
bits.data()->setFlags(RW_HAS_CXX_CTOR);
}
#endif
#if FAST_CACHE_HAS_CXX_DTOR
// 在 __LP64__ 的 __arm64__ 下是 0,在 !__arm64__ 下是 2。
// 直接判断 cache_t cache 的 uint16_t _flags 二进制表示的第 0/2 位的值是否为 1。
bool hasCxxDtor() {
ASSERT(isRealized());
return cache.getBit(FAST_CACHE_HAS_CXX_DTOR);
}
// 以原子方式把 cache_t cache 的 uint16_t _flags 二进制表示的第 0/2 位设置为 1。
void setHasCxxDtor() {
cache.setBit(FAST_CACHE_HAS_CXX_DTOR);
}
#else
// 直接判断 class_rw_t 的 uint32_t flags 二进制表示的第 17 位的值是否为 1。
bool hasCxxDtor() {
ASSERT(isRealized());
return bits.data()->flags & RW_HAS_CXX_DTOR;
}
// 以原子方式把 class_rw_t 的 uint32_t flags 二进制表示的第 17 位设置为 1。
void setHasCxxDtor() {
bits.data()->setFlags(RW_HAS_CXX_DTOR);
}
#endif
FAST_CACHE_REQUIRES_RAW_ISA/RW_REQUIRES_RAW_ISA
FAST_CACHE_REQUIRES_RAW_ISA 用以在 __LP64__ 平台下判断 objc_class 的 cache_t cache 的 uint16_t _flags 二进制表示时第 13 位的值是否为 1,以此表示类实例对象(此处是指类对象,不是使用类构建的实例对象,一定要记得)是否需要原始的 isa。而在 非 __LP64__ 且 SUPPORT_NONPOINTER_ISA 的平台下,则是使用 RW_REQUIRES_RAW_ISA,且判断的位置发生了变化,RW_REQUIRES_RAW_ISA 用以判断从 objc_class 的 class_data_bits_t bits 中取得 class_rw_t 指针指向的 class_rw_t 实例的 uint32_t flags 的第 15 位的值是否为 1,以此表示类实例对象(此处是指类对象,不是使用类构建的实例对象,一定要记得)是否需要原始的 isa。
#if __LP64__
...
// class's instances requires raw isa.
// 类实例需要 raw isa。
#define FAST_CACHE_REQUIRES_RAW_ISA (1<<13)
...
#else
...
// class's instances requires raw isa.
// 类实例需要 raw isa。
#if SUPPORT_NONPOINTER_ISA
#define RW_REQUIRES_RAW_ISA (1<<15)
#endif
...
#endif
instancesRequireRawIsa/setInstancesRequireRawIsa
在 __LP64__ 平台和其它平台下判断、设置类实例(此处是指类对象,不是使用类构建的实例对象,一定要记得)需要原始 isa 的标记位。
#if FAST_CACHE_REQUIRES_RAW_ISA
// 直接判断 cache_t cache 的 uint16_t _flags 二进制表示的第 13 位的值是否为 1。
bool instancesRequireRawIsa() {
return cache.getBit(FAST_CACHE_REQUIRES_RAW_ISA);
}
// 以原子方式把 cache_t cache 的 uint16_t _flags 二进制表示的第 13 位设置为 1。
void setInstancesRequireRawIsa() {
cache.setBit(FAST_CACHE_REQUIRES_RAW_ISA);
}
#elif SUPPORT_NONPOINTER_ISA
// 直接判断 class_rw_t 的 uint32_t flags 二进制表示的第 15 位的值是否为 1。
bool instancesRequireRawIsa() {
return bits.data()->flags & RW_REQUIRES_RAW_ISA;
}
// 以原子方式把 class_rw_t 的 uint32_t flags 二进制表示的第 15 位设置为 1。
void setInstancesRequireRawIsa() {
bits.data()->setFlags(RW_REQUIRES_RAW_ISA);
}
#else
// 当 isa 是原始 isa 时,直接返回 true。
bool instancesRequireRawIsa() {
return true;
}
void setInstancesRequireRawIsa() {
// nothing
}
#endif
- 当
! __LP64__平台下,所有掩码都存储在class_rw_t的uint32_t flags。 __LP64__平台下,FAST_HAS_DEFAULT_RR存储在class_data_bits_t bits的uintptr_t bits。(1UL<<2)(retain/release/autorelease/retainCount/_tryRetain/_isDeallocating/retainWeakReference/allowsWeakReference)__LP64__平台下,FAST_CACHE_HAS_DEFAULT_AWZ存储在cache_t cache的uint16_t _flags下。(1<<14)(alloc/allocWithZone:)__LP64__平台下,FAST_CACHE_HAS_DEFAULT_CORE存储在cache_t cache的uint16_t _flags下。(1<<15)(new/self/class/respondsToSelector/isKindOfClass)__LP64__平台下,FAST_CACHE_HAS_CXX_CTOR存储在cache_t cache的uint16_t _flags下。(1<<1)(.cxx_construct)__LP64__平台下,FAST_CACHE_HAS_CXX_DTOR存储在cache_t cache的uint16_t _flags下。(1<<2/1<<0)(.cxx_destruct)__LP64__平台下,FAST_CACHE_REQUIRES_RAW_ISA存储在cache_t cache的uint16_t _flags下。(1<<13)(requires raw isa)
void printInstancesRequireRawIsa(bool inherited)
打印类对象需要原始 isa,当环境变量 OBJC_PRINT_RAW_ISA Value 为 true 时会调用该函数,inherited 表示该类是否是一个子类。
OPTION( PrintRawIsa, OBJC_PRINT_RAW_ISA, "log classes that require raw pointer isa fields")
void
objc_class::printInstancesRequireRawIsa(bool inherited)
{
// 打印标识开启,否则执行断言
ASSERT(PrintRawIsa);
// 类对象需要原始的 isa,否则执行断言
ASSERT(instancesRequireRawIsa());
// 控制台输出需要原始 isa 的类名等信息
_objc_inform("RAW ISA: %s%s%s", nameForLogging(),
isMetaClass() ? " (meta)" : "",
inherited ? " (inherited)" : "");
}
void setInstancesRequireRawIsaRecursively(bool inherited = false)
将此类及其所有子类标记为需要原始 isa 指针,标记函数 setInstancesRequireRawIsa 很简单,上面我们已经分析过了, 这里涉及到一个更重要的知识点,就是我们如何才能获取一个类的所有子类呢 ?这里正式使用到了 struct class_rw_t 的两个成员变量 Class firstSubclass 和 Class nextSiblingClass,下面我们跟着函数调用流程一起来分析一下吧。
/*
* Mark this class and all of its subclasses as requiring raw isa pointers.
* 将此类及其所有子类标记为需要原始 isa 指针。
*/
void objc_class::setInstancesRequireRawIsaRecursively(bool inherited)
{
// struct objc_class 的函数内部的 this 自然是 objc_class *。
// 取得 objc_class 指针。
Class cls = (Class)this;
// 加锁,加锁失败则执行断言。
runtimeLock.assertLocked();
// 如果此类已经被标记为需要原始 isa,则直接 return。
if (instancesRequireRawIsa()) return;
// 枚举一个类及其所有已实现的子类。
//(foreach_realized_class_and_subclass 函数是我们要重点关注的对象,正是它获取了所有子类)
foreach_realized_class_and_subclass(cls, [=](Class c){
if (c->instancesRequireRawIsa()) {
// 如果此类已经被标记为需要原始 isa,则直接 return false,跳过该类继续遍历下一个子类。
return false;
}
// 把 c 标记为需要原始 isa。
c->setInstancesRequireRawIsa();
// 是否在控制台打印
if (PrintRawIsa) c->printInstancesRequireRawIsa(inherited || c != cls);
// return true 继续执行遍历。
return true;
});
}
foreach_realized_class_and_subclass
// Enumerates a class and all of its realized subclasses.
// 枚举一个类及其所有已实现的子类。
static void
foreach_realized_class_and_subclass(Class top, bool (^code)(Class) __attribute((noescape)))
{
unsigned int count = unreasonableClassCount();
foreach_realized_class_and_subclass_2(top, count, false, code);
}
unreasonableClassCount
/*
* unreasonableClassCount
* Provides an upper bound for any iteration of classes,
* to prevent spins when runtime metadata is corrupted.
* 为类的任何迭代提供上限,以防止在运行时元数据损坏时发生死循环。
*/
static unsigned unreasonableClassCount()
{
// 加锁
runtimeLock.assertLocked();
int base = NXCountMapTable(gdb_objc_realized_classes) +
getPreoptimizedClassUnreasonableCount();
// Provide lots of slack here. Some iterations touch metaclasses too.
// 在此处提供大量的余地。一些迭代也涉及元类。
// Some iterations backtrack (like realized class iteration).
// 一些迭代回溯(例如实现的类迭代)。
// We don't need an efficient bound, merely one that prevents spins.
// 我们不需要有效的界限,只需防止旋转即可。
return (base + 1) * 16;
}
foreach_realized_class_and_subclass_2
/*
* Class enumerators 类枚举器
* The passed in block returns `false` if subclasses can be skipped.
* 如果可以跳过子类,则传入的块将返回 "false"。
* Locking: runtimeLock must be held by the caller.
* runtimeLock 必须由调用方持有。
*/
// foreach_realized_class_and_subclass_2(top, count, false, code);
// top 是当前类,skip_metaclass 值是 false,code 就是我们枚举时的块
// __attribute((noescape)) 想到了 Swift 中的闭包
static inline void
foreach_realized_class_and_subclass_2(Class top, unsigned &count,
bool skip_metaclass,
bool (^code)(Class) __attribute((noescape)))
{
Class cls = top;
runtimeLock.assertLocked();
ASSERT(top);
while (1) {
if (--count == 0) {
_objc_fatal("Memory corruption in class list.");
}
bool skip_subclasses;
if (skip_metaclass && cls->isMetaClass()) {
skip_subclasses = true;
} else {
skip_subclasses = !code(cls);
}
if (!skip_subclasses && cls->data()->firstSubclass) {
cls = cls->data()->firstSubclass;
} else {
while (!cls->data()->nextSiblingClass && cls != top) {
cls = cls->superclass;
if (--count == 0) {
_objc_fatal("Memory corruption in class list.");
}
}
if (cls == top) break;
cls = cls->data()->nextSiblingClass;
}
}
}
bool canAllocNonpointer()
表示 objc_class 的 isa 是非指针,即类对象不需要原始 isa 时,能根据该函数返回值设置 isa_t isa 的 uintptr_t nonpointer : 1 字段,标记该类的 isa 是非指针。
bool canAllocNonpointer() {
ASSERT(!isFuture());
return !instancesRequireRawIsa();
}
bool isSwiftStable()
调用 class_data_bits_t bits 的 isSwiftStable 函数,内部实现是通过与操作判断 uintptr_t bits 的二进制表示的第 1 位是否是 1,表示该类是否是有稳定的 Swift ABI 的 Swift 类。
// class is a Swift class from the stable Swift ABI.
// class 是一个有稳定的 Swift ABI 的 Swift 类。
// #define FAST_IS_SWIFT_STABLE (1UL<<1)
bool isSwiftStable() {
return bits.isSwiftStable();
}
bool isSwiftLegacy()
调用 class_data_bits_t bits 的 isSwiftLegacy 函数,内部实现是通过与操作判断 uintptr_t bits 的二进制表示的第 0 位是否是 1,表示该类是否是有稳定的 Swift ABI 的 Swift 类。(遗留的类)
// class is a Swift class from the pre-stable Swift ABI.
// class 是来自稳定的 Swift ABI 的 Swift 类。(遗留的类)
// #define FAST_IS_SWIFT_LEGACY (1UL<<0)
bool isSwiftLegacy() {
return bits.isSwiftLegacy();
}
bool isAnySwift()
调用 class_data_bits_t bits 的 isAnySwift 函数,isSwiftStable 或者 isSwiftLegacy。
bool isAnySwift() {
return bits.isAnySwift();
}
// struct class_data_bits_t 的 isAnySwift 函数实现:
bool isAnySwift() {
return isSwiftStable() || isSwiftLegacy();
}
bool isSwiftStable_ButAllowLegacyForNow()
调用 struct class_data_bits_t 的 isSwiftStable_ButAllowLegacyForNow 函数。
bool isSwiftStable_ButAllowLegacyForNow() {
return bits.isSwiftStable_ButAllowLegacyForNow();
}
// struct class_data_bits_t 的 isSwiftStable_ButAllowLegacyForNow 函数实现
// fixme remove this once the Swift runtime uses the stable bits.
// fixme 一旦 Swift runtime 使用稳定位将其删除。
bool isSwiftStable_ButAllowLegacyForNow() {
return isAnySwift();
}
bool isAnySwift() {
return isSwiftStable() || isSwiftLegacy();
}
bool isStubClass() const
全局搜索此函数发现只在 objc_class 的 bool isRealized() const 函数内调用了一次,它用于判断类对象是否已经实现完成。
bool isStubClass() const {
// isaBits 函数继承自 struct objc_object,
// 它的实现只有一行就是取出 isa_t isa 的 uintptr_t bits 成员变量。
// 如果 isa 是原始指针的话,那么取出的值是一个内存地址被强转为一个 unsigned long 值,
// 即使 isa 不是原始的 isa,是一个优化的 isa,那它强转为 unsigned long 的值的话也会远大于 16 吧
uintptr_t isa = (uintptr_t)isaBits();
return 1 <= isa && isa < 16;
}
bool isUnfixedBackwardDeployingStableSwift()
// Swift stable ABI built for old deployment targets looks weird.
// 为旧的部署目标构建的 Swift 稳定的 ABI 看起来很奇怪。
// The is-legacy bit is set for compatibility with old libobjc.
// 设置 is-legacy 位是为了与旧的 libobjc 兼容。
// We are on a "new" deployment target so we need to rewrite that bit.
// 我们的部署目标是“新的”,因此我们需要重写一下。
// These stable-with-legacy-bit classes are distinguished from real
// legacy classes using another bit in the Swift data.
// 这些具有传统稳定性的类使用 Swift 数据中的另一位与实际的传统类区分开.
// (ClassFlags::IsSwiftPreStableABI)
bool isUnfixedBackwardDeployingStableSwift() {
// Only classes marked as Swift legacy need apply.
// 仅需要标记为 Swift legacy 的类适用。
if (!bits.isSwiftLegacy()) return false;
// Check the true legacy vs stable distinguisher.
// 检查真正的传统 vs 稳定的区分符。
// The low bit of Swift's ClassFlags is SET for true
// legacy and UNSET for stable pretending to be legacy.
// Swift 的 ClassFlags 的低位设置为 SET(表示真正的遗留物),而 UNSET(低位)用于稳定地假装为遗留物。
// 用 & 取出 class_data_bits_t bits 的地址加 1 是什么操作,
// struct class_data_bits 只有一个成员变量 uintptr_t bits,
// 那对 class_data_bits_t bits 取地址取出也是 uintptr_t bits 的地址,
// 通过前面的分析我们已知 uintptr_t bits 的第 0 位是标记 #define FAST_IS_SWIFT_LEGACY (1UL<<0),
// 这里的加 1 操作....
// 对 bits 的地址加 1,
uint32_t swiftClassFlags = *(uint32_t *)(&bits + 1);
bool isActuallySwiftLegacy = bool(swiftClassFlags & 1);
return !isActuallySwiftLegacy;
}
fixupBackwardDeployingStableSwift
void fixupBackwardDeployingStableSwift() {
if (isUnfixedBackwardDeployingStableSwift()) {
// Class really is stable Swift, pretending to be pre-stable.
// 类确实是稳定的 Swift,假装是稳定的。
// Fix its lie.
// 修正谎言
// 把 class_data_bits_t bits 的 uintptr_t bits 的 #define FAST_IS_SWIFT_STABLE (1UL<<1)
// 置为 1, 并把 #define FAST_IS_SWIFT_LEGACY (1UL<<0) 置为 0。
bits.setIsSwiftStable();
}
}
// 暂时不理解是干啥用的
_objc_swiftMetadataInitializer swiftMetadataInitializer() {
return bits.swiftMetadataInitializer();
}
下面的一些掩码相关的操作我们开始用到 struct class_ro_t 的 uint32_t flags了!它们的宏定义都是以 RO_ 开头的。
RO_IS_ARC/RO_HAS_WEAK_WITHOUT_ARC
在 struct class_ro_t 的 uint32_t flags 中使用的掩码。
// class compiled with ARC
// 由 ARC 编译的类
#define RO_IS_ARC (1<<7)
// class is not ARC but has ARC-style weak ivar layout.
// 类不是 ARC,但具有 ARC 风格的 weak ivar 布局。
#define RO_HAS_WEAK_WITHOUT_ARC (1<<9)
bool hasAutomaticIvars()
从 class_data_bits_t bits 中取出 class_rw_t 指针,然后从 struct class_rw_t 中取出 explicit_atomic<uintptr_t> ro_or_rw_ext 对应的 class_rw_ext_t 指针,然后从 struct class_rw_ext_t 中取出 const class_ro_t *ro,然后取出 uint32_t flags 和 (RO_IS_ARC | RO_HAS_WEAK_WITHOUT_ARC (二进制表示第 7 位和第 9 位是 1,其它位都是 0))做与操作。
// Return YES if the class's ivars are managed by ARC, or the class is MRC but has ARC-style weak ivars.
// 如果类的 ivars 由 ARC 管理,或者该类是 MRC 但具有 ARC 样式的 weak ivars,则返回 YES。
// (weak 修饰符是可以在 MRC 中使用的,weak 是和 ARC 一起推出的,
// 根据之前 weak 的实现原理也可知它的实现流程和 ARC 或者 MRC 是完成没有关系的。)
bool hasAutomaticIvars() {
return data()->ro()->flags & (RO_IS_ARC | RO_HAS_WEAK_WITHOUT_ARC);
}
bool isARC()
同上,最后取出 class_ro_t 的 uint32_t flags 和 RO_IS_ARC 做与操作。
// Return YES if the class's ivars are managed by ARC.
// 如果类的 ivar 由 ARC 管理,则返回 YES。
bool isARC() {
return data()->ro()->flags & RO_IS_ARC;
}
RW_FORBIDS_ASSOCIATED_OBJECTS
禁止类的实例对象进行关联对象的掩码,看到它前缀是 RW 开始的,表示它用在 struct class_rw_t 的 uint32_t flags 中。(AssociatedObject 的实现原理可以参考之前的文章)
// class does not allow associated objects on its instances.
// 类不允许在其实例上使用 关联对象。
#define RW_FORBIDS_ASSOCIATED_OBJECTS (1<<20)
bool forbidsAssociatedObjects()
禁止该类的实例对象进行 AssociatedObject。从 class_data_bits_t bits 中取出 class_rw_t 指针,然后从 struct class_rw_t 中取出 uint32_t flags 和 RW_FORBIDS_ASSOCIATED_OBJECTS(第 20 位值为 1)与操作的结果。
bool forbidsAssociatedObjects() {
// class_rw_t 的 flags 做与操作
return (data()->flags & RW_FORBIDS_ASSOCIATED_OBJECTS);
}
instancesHaveAssociatedObjects/setInstancesHaveAssociatedObjects
在 struct class_rw_t 的 uint32_t flags 做掩码操作。
// class instances may have associative references.
// 类实例可能具有关联引用。
#define RW_INSTANCES_HAVE_ASSOCIATED_OBJECTS (1<<22)
#if SUPPORT_NONPOINTER_ISA
// Tracked in non-pointer isas; not tracked otherwise
#else
bool instancesHaveAssociatedObjects() {
// this may be an unrealized future class in the CF-bridged case.
// 在 CF 桥接的情况下,这可能是未实现的未来 class。
ASSERT(isFuture() || isRealized());
// class_rw_t 的 flags
return data()->flags & RW_INSTANCES_HAVE_ASSOCIATED_OBJECTS;
}
void setInstancesHaveAssociatedObjects() {
// this may be an unrealized future class in the CF-bridged case.
// 在CF桥接的情况下,这可能是未实现的未来 class。
ASSERT(isFuture() || isRealized());
// class_rw_t 的 flags
setInfo(RW_INSTANCES_HAVE_ASSOCIATED_OBJECTS);
}
#endif
shouldGrowCache/setShouldGrowCache
// 默认为 true
bool shouldGrowCache() {
return true;
}
void setShouldGrowCache(bool) {
// fixme good or bad for memory use?
}
RW_INITIALIZING
判断 objc_class 是否正在进行初始化的掩码。判断位置在 struct class_rw_t 的 uint32_t flags 中。
// class is initializing
// class 正在初始化 (class_rw_t flags 的 第 28 位)
#define RW_INITIALIZING (1<<28)
bool isInitializing()
&esmp;RW_INITIALIZING 是 RW 前缀开头,可直接联想到其判断位置在 struct class_rw_t 的 uint32_t flags 中,与前面的一些判断相比这里 objc_class 的位置发生了变化,前面我们所有的判断都是在当前的 objc_class 中进行的,而此处的判断要转移到当前 objc_class 的元类中,元类的类型也是 struct objc_class,所以它们同样也有 class_data_bits_t bits、cache_t cache 等成员变量,这里 isInitializing 函数使用的正是元类的 class_data_bits_t bits 成员变量。getMeta 函数是取得当前 objc_class 的元类,然后 data 函数从元类的 class_data_bits_t bits 中取得 class_rw_t 指针,然后取得 struct class_rw_t 的 uint32_t flags 和 RW_INITIALIZING 做与操作,取得 flags 二进制表示的第 28 位的值作为结果返回。
bool isInitializing() {
return getMeta()->data()->flags & RW_INITIALIZING;
}
void setInitialized()
标记该类初始化完成。
/*
* Locking: write-locks runtimeLock
* 此过程需要加锁
*/
void
objc_class::setInitialized()
{
// 记录当前类的元类的临时变量
Class metacls;
// 记录当前类的临时变量
Class cls;
// 如果当前类是元类,则执行断言
ASSERT(!isMetaClass());
// 当前类
cls = (Class)this;
// 元类
metacls = cls->ISA();
// 加锁
mutex_locker_t lock(runtimeLock);
// Special cases:
// 特别情况
// - NSObject AWZ class methods are default.
// - NSObject RR class and instance methods are default.
// - NSObject Core class and instance methods are default.
// adjustCustomFlagsForMethodChange() also knows these special cases.
// attachMethodLists() also knows these special cases.
objc::AWZScanner::scanInitializedClass(cls, metacls);
objc::RRScanner::scanInitializedClass(cls, metacls);
objc::CoreScanner::scanInitializedClass(cls, metacls);
// Update the +initialize flags.
// 更新 +initialize 字段。
// Do this last.
// 设置元类的 RW_INITIALIZED 标记位,并清除 RW_INITIALIZING 标记位
//(struct class_rw_t 的 uint32_t flags 成员变量)
metacls->changeInfo(RW_INITIALIZED, RW_INITIALIZING);
}
bool isLoadable()
默认为 true。
bool isLoadable() {
ASSERT(isRealized());
// any class registered for +load is definitely loadable.
return true;
}
IMP getLoadMethod()
获取一个类的 +load 函数,首先我们要对 +load 函数和别的函数做出一些理解上的区别,首先我们在任何时候都不应该自己主动去调用 +load 函数,它是由系统自动调用的,且它被系统调用时是直接通过它的函数地址调用的,它是不走 objc_msgSend 消息发送流程的。当我们在自己的类定义中添加了 +load 函数,编译过程中编译器会把它存储在元类的 struct class_ro_t 的 method_list_t * baseMethodList 成员变量中。那么 category 中的 +load 函数在编译过程中会被放在哪里呢?
/*
* objc_class::getLoadMethod
* fixme
* Called only from add_class_to_loadable_list.
* 仅从 add_class_to_loadable_list 调用。
* Locking: runtimeLock must be read- or write-locked by the caller.
* Locking: runtimeLock 必须是读写锁。
*/
IMP
objc_class::getLoadMethod()
{
// 加锁
runtimeLock.assertLocked();
// 临时变量,const 表示 mlist 指向的 method_list_t 不可变。
const method_list_t *mlist;
// 当前 objc_class 和其元类 已经实现完成,
// 当前 objc_class 不能是元类,且它的 ISA() 是元类
ASSERT(isRealized());
ASSERT(ISA()->isRealized());
ASSERT(!isMetaClass());
ASSERT(ISA()->isMetaClass());
// 获取当前类的元类的 class_ro_t 的 method_list_t * baseMethodList
mlist = ISA()->data()->ro()->baseMethods();
// 如果 mlist 存在,则遍历找到 +load 函数
if (mlist) {
for (const auto& meth : *mlist) {
// 取得函数的名字 (SEL)
const char *name = sel_cname(meth.name);
// 如果是 +load 函数,则直接返回 +load 函数的 imp
if (0 == strcmp(name, "load")) {
return meth.imp;
}
}
}
// 如果没有找到则返回 nil
return nil;
}
RW_REALIZED
在 struct class_rw_t 的 uint32_t flags 二进制表示的第 31 位
#define RW_REALIZED (1<<31)
bool isRealized() const
struct class_rw_t 的 uint32_t flags 二进制表示的第 31 位和 RW_REALIZED 与操作的结果。
// Locking: To prevent concurrent realization, hold runtimeLock.
// Locking: 为了防止并发实现,需要加锁。
bool isRealized() const {
return !isStubClass() && (data()->flags & RW_REALIZED);
}
RW_FUTURE
// class is unresolved future class.
// class 是未解决的 future class。
#define RW_FUTURE (1<<30)
bool isFuture() const
struct class_rw_t 的 uint32_t flags 二进制表示的第 30 位和 RW_REALIZED 与操作的结果。
// Returns true if this is an unrealized future class.
// 如果这是未实现的 future class,则返回true。
// Locking: To prevent concurrent realization, hold runtimeLock.
// Locking: 为了防止并发实现,需要加锁。
bool isFuture() const {
return data()->flags & RW_FUTURE;
}
FAST_CACHE_META/RW_META/RO_META
在 __LP64__ 平台下标识 objc_class 是否是元类的值在 cache_t cache 中,其它情况则是在 struct class_rw_t 的 uint32_t flags 中(需要根据指针进行寻址)。
// class is a metaclass.
// 类是元类。
#define RO_META (1<<0)
// class is a metaclass (copied from ro).
// 类是元类。
#define RW_META RO_META // (1<<0)
#if __LP64__
...
#if __arm64__
...
// Denormalized RO_META to avoid an indirection.
// 为避免间接化,对 RO_META 进行了规范化处理。
#define FAST_CACHE_META (1<<2)
#else
// Denormalized RO_META to avoid an indirection.
// 为避免间接化,对 RO_META 进行了规范化处理。
#define FAST_CACHE_META (1<<0)
...
#endif
...
#else
...
#endif
bool isMetaClass()
如果 FAST_CACHE_META 存在,则从 cache_t cache 的 uint16_t _flags 二进制表示的第 2/0 位判断当前 objc_class 是否是元类。其它情况则从 class_data_bits_t bits 中取得 class_rw_t 指针指向的 class_rw_t 实例的 uint32_t flags 二进制表示的第 0 位进行判断。
bool isMetaClass() {
ASSERT(this);
ASSERT(isRealized());
#if FAST_CACHE_META
return cache.getBit(FAST_CACHE_META);
#else
return data()->flags & RW_META;
#endif
}
bool isMetaClassMaybeUnrealized()
// Like isMetaClass, but also valid on un-realized classes.
// 类似于 isMetaClass,但在未实现的类上也有效。
bool isMetaClassMaybeUnrealized() {
static_assert(offsetof(class_rw_t, flags) == offsetof(class_ro_t, flags), "flags alias");
static_assert(RO_META == RW_META, "flags alias");
// 同上,从 struct class_rw_t 的 uint32_t flags 中判断
return data()->flags & RW_META;
}
Class getMeta()
取得当前类的元类。
// NOT identical to this->ISA when this is a metaclass.
Class getMeta() {
// 如果当前类是元类,则直接返回 this,
// 如果不是元类,则调用 objc_object::ISA() 函数取得元类。
//(多半是从 isa 中根据掩码取出类的地址:(Class)(isa.bits & ISA_MASK))
if (isMetaClass()) return (Class)this;
else return this->ISA();
}
bool isRootClass()
判断一个类是否是根类,只是判断一个类的 superclass 是否为 nil。
- 根类的父类是
nil,根类的元类是根元类。 - 根元类的父类是根类,根元类的元类是自己。
bool isRootClass() {
// 如果 objc_class 的 superclass 是 nil,则该类是根类。
return superclass == nil;
}
bool isRootMetaclass()
根元类的元类指向自己。
bool isRootMetaclass() {
// 如果一个 objc_class 的元类是自己的话,那么只可能是根元类。
return ISA() == (Class)this;
}
const char *mangledName()
伪装一个类的名字,看到其是保存在 struct class_ro_t 的 const char * name 内。
const char *mangledName() {
// fixme can't assert locks here
// fixme 不能在这里断言锁
ASSERT(this);
if (isRealized() || isFuture()) {
// 如果类已经实现了则 data() 返回的是 class_rw_t *,
// 然后再从 class_rw_ext_t * 返回 const class_ro_t *ro,
// 然后再返回 struct class_ro_t 的 const char * name。
return data()->ro()->name;
} else {
// data() 返回的是 class_ro_t *,
// 然后返回 const char * name。
return ((const class_ro_t *)data())->name;
}
}
const char *demangledName(bool needsLock);
const char *nameForLogging();
word_align
根据入参 x 进行 8/4 字节对齐。
#ifdef __LP64__
...
# define WORD_MASK 7UL
...
#else
...
# define WORD_MASK 3UL
...
#endif
static inline uint32_t word_align(uint32_t x) {
// __LP64__ 下 WORD_MASK 7UL :
// x = 12 => 0b 0000 0000 0000 0000 0000 0000 0000 1100
// WORD_MASK => 0b 0000 0000 0000 0000 0000 0000 0000 0111
// ~WORD_MASK => 0b 1111 1111 1111 1111 1111 1111 1111 1000
// x + WORD_MASK => 0b 0000 0000 0000 0000 0000 0000 0001 0011
// & ~WORD_MASK => 0b 0000 0000 0000 0000 0000 0000 0001 0000
// 16
return (x + WORD_MASK) & ~WORD_MASK;
}
uint32_t unalignedInstanceStart() const
unalignedInstanceStart 只是表示第一个成员变量的所占用的字节大小吗?(如之前定义的一个继承自 NSObject 的类的 instanceStart 的值是 8)
// May be unaligned depending on class's ivars.
// 根据 class 的 ivars 可能没有内存对齐。
uint32_t unalignedInstanceStart() const {
ASSERT(isRealized());
// 直接返回 struct class_ro_t 的 uint32_t instanceStart
return data()->ro()->instanceStart;
}
uint32_t alignedInstanceStart() const
// Class's instance start rounded up to a pointer-size boundary.
// 类的实例开始四舍五入到指针大小的边界。
// This is used for ARC layout bitmaps.
// 这用于 ARC 布局位图。
uint32_t alignedInstanceStart() const {
// 调用 word_align 工具函数,计算一个大于等于入参的最小的 8 的倍数。
// 如 x = 7 返回 8
// 如 x = 8 返回 8
// 如 x = 12 返回 16
// ...
return word_align(unalignedInstanceStart());
}
uint32_t unalignedInstanceSize() const
// May be unaligned depending on class's ivars.
// 根据 class 的 ivars 可能没有内存对齐。
uint32_t unalignedInstanceSize() const {
ASSERT(isRealized());
// 直接返回 struct class_ro_t 的 uint32_t instanceSize
// 根据内存对齐计算成员变量从前到后所占用的内存大小,
// 不过没有进行总体的内存对齐,例如最后一个成员变量是 char 时,
// 则最后只是加 1,instanceSize 的值是一个奇数,
// 再进行一个整体 8 字节对齐就好了,
// alignedInstanceSize 函数,完成了这最后一步的整体内存对齐
return data()->ro()->instanceSize;
}
uint32_t alignedInstanceSize() const
// Class's ivar size rounded up to a pointer-size boundary.
// 类的ivar大小四舍五入到指针大小的边界。
//(对 instanceSize 进行 8 字节对齐)
uint32_t alignedInstanceSize() const {
// __LP64__ 平台下 8 字节对齐,其它则是 4 字节对齐
return word_align(unalignedInstanceSize());
}
size_t instanceSize(size_t extraBytes) const
size_t instanceSize(size_t extraBytes) const {
// 从 cache_t cache 的 uint16_t _flags 判断是否能快速获取实例大小
if (fastpath(cache.hasFastInstanceSize(extraBytes))) {
return cache.fastInstanceSize(extraBytes);
}
// 正常调用 alignedInstanceSize 并添加需要延展的 bytes。
size_t size = alignedInstanceSize() + extraBytes;
// CF requires all objects be at least 16 bytes.
// CF要求所有对象至少为 16 个字节。
if (size < 16) size = 16;
return size;
}
void setInstanceSize(uint32_t newSize)
cache.setFastInstanceSize(newSize) 把类实例的大小放在了 cache_t cache 的 uint16_t _flags 中,方便进行快速获取,减少了 class_rw_t 指针的寻址。
void setInstanceSize(uint32_t newSize) {
ASSERT(isRealized());
ASSERT(data()->flags & RW_REALIZING);
// 取得 class_ro_t
auto ro = data()->ro();
if (newSize != ro->instanceSize) {
// 如果 newSize 不等于 ro->instanceSize
ASSERT(data()->flags & RW_COPIED_RO);
// 更新 instanceSize
*const_cast<uint32_t *>(&ro->instanceSize) = newSize;
}
// 把 newSize 保存在 cache_t cache 的 uint16_t _flags 中,方便进行快速获取,减少了 class_rw_t 指针的寻址
cache.setFastInstanceSize(newSize);
}
chooseClassArrayIndex/setClassArrayIndex/classArrayIndex
关于类在全局类表中的索引,这里不再展开了。
至此,objc_class 的所有函数就全部看完了。
参考链接
参考链接:🔗