美文网首页
12期_iOS_探究iSA

12期_iOS_探究iSA

作者: 萧修 | 来源:发表于2023-08-13 01:00 被阅读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;
}
  • ASSERT(!isTaggedPointer());
    首先断言判断,是否是小对象,不是小对象,执行下面语句

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大小为8字节。
  • 联合体内部的元素在内存中是互相覆盖,所以cls和bits不会同时存在

联合体内部又增加了位域结构使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

相关文章

  • 类的分析、探索

    类的isa探究 准备研究类LGPerson类。沿用探究oc对象的思路,使用lldb先从类的内存、isa来进行观察。...

  • 03 isa探究

    iOS开发者一定知道每个实例对象都有一个isa指针,其中存储着对象的类信息。今天我们就来探究下isa是如何保存类的...

  • iOS底层-isa结构(isa_t)

    在iOS 底层-- isa指向探究中探索了isa的指向,那么isa的结构具体是什么样的。从源码中来着手研究。 一、...

  • iOS底层 - cache原理分析

    iOS开发底层探究之路 在对Objective-C底层的探究过程中,已经探究过objc_class 结构中的isa...

  • iOS底层原理探究05-类的底层原理isa链&继承链&类的内存结

    isa指向分析 通过《iOS底层原理探究04-OC对象的本质&联合体位域&isa分析》[https://www.j...

  • 2019-03-02

    Runtime Objective-C Runtime iOS底层原理探究-Runtime isa 和 Class...

  • 探究isa指针本质

    和之前一样,也是从源码中找到答案。我们都知道,实例对象的isa指针指向类对象,类对象的isa指针指向元类对象。 1...

  • iOS 底层-- isa探究

    关系总揽 ⬇️首先你需要知道有这张图的存在,具体关系在下面在一步一步来验证 1、对象isa指向 基础概念 实例对象...

  • isa-swizzling到底为何物?

    isa-swizzling到底为何物~ 抱着学习的心态,我想对它一探究竟。 isa-swizzling其实就是一种...

  • 联合体与位域

    在对 OC 对象创建的探究过程中,我们发现一个很有趣的实现 isa。isa 是将对象内存空间与 class 之间联...

网友评论

      本文标题:12期_iOS_探究iSA

      本文链接:https://www.haomeiwen.com/subject/bsmvpdtx.html