问题: 简述一下 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对象.


IT界无底坑洞栋主 欢迎加Q骚扰:676758285