12期_iOS_探究iSA

2023-08-13  本文已影响0人  萧修

引入一个nonpointer概念

早期调用isa可以返回类,后来苹果为了优化内存,使其内部增加了及其丰富的信息,并且增加了isa_mask,不让直接获取类,有优化就是nonpointer

isa简介

从初始化isa源码入手分析

inline void 
objc_object::initIsa(Class cls, bool nonpointer, UNUSED_WITHOUT_INDEXED_ISA_AND_DTOR_BIT bool hasCxxDtor)
{ 
    ASSERT(!isTaggedPointer()); 
    
    isa_t newisa(0);

    if (!nonpointer) {
        newisa.setClass(cls, this);
    } else {
        ASSERT(!DisableNonpointerIsa);
        ASSERT(!cls->instancesRequireRawIsa());


#if SUPPORT_INDEXED_ISA
        ASSERT(cls->classArrayIndex() > 0);
        newisa.bits = ISA_INDEX_MAGIC_VALUE;
        // isa.magic is part of ISA_MAGIC_VALUE
        // isa.nonpointer is part of ISA_MAGIC_VALUE
        newisa.has_cxx_dtor = hasCxxDtor;
        newisa.indexcls = (uintptr_t)cls->classArrayIndex();
#else
        newisa.bits = ISA_MAGIC_VALUE;
        // isa.magic is part of ISA_MAGIC_VALUE
        // isa.nonpointer is part of ISA_MAGIC_VALUE
#   if ISA_HAS_CXX_DTOR_BIT
        newisa.has_cxx_dtor = hasCxxDtor;
#   endif
        newisa.setClass(cls, this);
#endif
        newisa.extra_rc = 1;
    }

    // This write must be performed in a single store in some cases
    // (for example when realizing a class because other threads
    // may simultaneously try to use the class).
    // fixme use atomics here to guarantee single-store and to
    // guarantee memory order w.r.t. the class index table
    // ...but not too atomic because we don't want to hurt instantiation
    isa = newisa;
}

isa_t newisa(0)初始化isa_t

if (!nonpointer)判断是否优化,未开启优化,直接关联
newisa.setClass(cls, this);否则执行

从这里可以看出isa_t才是isa的真正的结构

isa的数据结构

代码如下

union isa_t {
    isa_t() { }
    isa_t(uintptr_t value) : bits(value) { }

    uintptr_t bits;

private:
    Class cls;
    
public:
#if defined(ISA_BITFIELD)
    struct {
        ISA_BITFIELD;  // defined in isa.h
    };

#endif
};

看出isa_t是联合体+位域

联合体内部又增加了位域结构使isa更加丰富,接下来,我们来看ISA_BITFIELD

#   define ISA_BITFIELD
      uintptr_t nonpointer        : 1;
      uintptr_t has_assoc         : 1;
      uintptr_t has_cxx_dtor      : 1;
      uintptr_t shiftcls          : 44; /*MACH_VM_MAX_ADDRESS 0x7fffffe00000*/ \
      uintptr_t magic             : 6;
      uintptr_t weakly_referenced : 1;
      uintptr_t unused            : 1;
      uintptr_t has_sidetable_rc  : 1;
      uintptr_t extra_rc          : 8

nonpointer:表示是否对isa指针开启优化(0:纯isa指针,1:不止是类对象地址,还包含了类信息,对象的引用计数等)
has_assoc:关联对象标志位(0没有,1存在)
has_cxx_dtor:该对象是否有C++或者Objc的析构器,如果有析构函数,则需要做析构逻辑,如果没有,可以更快释放对象
shiftcls:存储类指针的值。开启指针优化的情况,在arm64架构下,有33位用来存储类指针
magic:用于调试器判断当前对象是真的对象,还是没有初始化的空间
weakly_referenced:对象是否被指向或者曾经指向一个ARC的弱变量,没有弱引用的变量可以更快释放。
deallocating:标志对象是否正在释放内存
has_sidetable_rc:当对象的引用计数大于10时,则需要该变量存储进位
extra_rc:表示该对象的引用计数值,实际上引用计数值减1,例如如果引用对象为10,那么该值为9,如引用计数大于10,则需要用到has_sidetable_rc

上一篇 下一篇

猜你喜欢

热点阅读