问题: 简述一下 isa指针 的底层结构.
isa指针在arm32位直接存储的内容就是class或者meta-class地址信息.
在arm32时代, isa指针就是一个内存地址, 但是在 arm64 架构下,isa是一个共用体.
但isa指针在arm64位也就是armv8架构下需要做一次位运算 (&ISA_MASK) 才能获得class或者meta-class的地址信息.
# if __arm64__
# if __has_feature(ptrauth_calls) || TARGET_OS_SIMULATOR
# define ISA_MASK 0x007ffffffffffff8ULL
...
# else
# define ISA_MASK 0x0000000ffffffff8ULL
...
# endif
# elif __x86_64__
# define ISA_MASK 0x00007ffffffffff8ULL
...
# else
# error unknown architecture for packed isa
# endif
union isa_t{
isa_t() { }
isa_t(uintptr_t value) : bits(value) { }
uintptr_t bits;
...
}
在 isa.h
中,含有位域和掩码信息,这里只截取iPhoneOS 真机情况下的相关内容.
# if __arm64__
// ARM64 simulators have a larger address space, so use the ARM64e
// scheme even when simulators build for ARM64-not-e.
# if __has_feature(ptrauth_calls) || TARGET_OS_SIMULATOR
...
# else
# define ISA_MASK 0x0000000ffffffff8ULL
# define ISA_MAGIC_MASK 0x000003f000000001ULL
# define ISA_MAGIC_VALUE 0x000001a000000001ULL
# define ISA_HAS_CXX_DTOR_BIT 1
# define ISA_BITFIELD \
uintptr_t nonpointer : 1; \
uintptr_t has_assoc : 1; \
uintptr_t has_cxx_dtor : 1; \
uintptr_t shiftcls : 33; /*MACH_VM_MAX_ADDRESS 0x1000000000*/ \
uintptr_t magic : 6; \
uintptr_t weakly_referenced : 1; \
uintptr_t unused : 1; \
uintptr_t has_sidetable_rc : 1; \
uintptr_t extra_rc : 19
# define RC_ONE (1ULL<<45)
# define RC_HALF (1ULL<<18)
# endif
其中,各个位域的信息如下所示.
- nonpointer : 是否不是一个纯粹的ISA指针的标志位.
- has_assoc : 是否
设置过
关联对象的标志位. - has_cxx_dtor : (.cxx_destruct) 是否还有C++的析构函数,如果没有,则释放的更快.
- shiftcls : ISA指针的地址值.
- magic : 用于调试的时候判断对象是否已经初始化完成.
- weakly_referenced : 是否被弱引用
指向过
,如果没有,则释放的更快. - unused : 暂无找到官方解释.
- extra_rc : 用来存放引用计数.
- has_sidetable_rc : 如果 has_extra_rc 位数不够用,引用计数放于别处,标志位就置为 1 .
问题: 简述一下isa指针和superclass指针的指向问题.
instance对象的isa指针指向于class对象.
class对象的isa指针是指向于meta-class对象.
所有的meta-class的isa指针指向于root-meta-class.
大部分meta-class和class对象的superclass指针指向于父类.
NSObject的class对象 superclass指针指向于nil.
NSObject的meta-class对象 superclass指针并非指向于nil,而是指向于NSObject的class对象.
Comments | 0 条评论