美文网首页
ISA结构分析

ISA结构分析

作者: 8ef7f923f5bb | 来源:发表于2020-09-13 12:07 被阅读0次

了解对象

Objective-C是一门面向对象编程语言。对象是什么,我们这篇文章讲的isa和对象又有什么样的关系呢?
带着疑问我们可以去看看苹果开源源码。
在其中找到了对object的定义:

/// Represents an instance of a class.
struct objc_object {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};

objc_object表示类的实例,就是我们通常说的对象。

LGPerson *objc = [[LGPerson alloc] init];
Class p1 = [objc class];
Class p2 = [LGPerson class];
打印结果p1:0x1000020f8  p2:0x1000020f8

struct objc_class : objc_object {
    // Class ISA;
    Class superclass;
    cache_t cache;             // formerly cache pointer and vtable
    class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags
    ...
}

p1通过object_getClass获取到isa指向的类对象,p2通过类名也获取到一摸一样的对象。
从源码可以看到objc_class是继承自objc_object且其中也有isa。这是不是意味着类也是读对象。而且我们还可以得出一个结论类对象在内存中仅存在一份。

isa是什么

我们在研究对象初始化的时候,曾经跟随底层源码看到了其中有这么一段代码

inline void 
objc_object::initIsa(Class cls, bool nonpointer, bool hasCxxDtor) 
{ 
    ASSERT(!isTaggedPointer()); 
    if (!nonpointer) {
        isa = isa_t((uintptr_t)cls);
    } else {
        ASSERT(!DisableNonpointerIsa);
        ASSERT(!cls->instancesRequireRawIsa());
        isa_t newisa(0);
        ...
        isa = newisa;
    }
}
isa_t isa;

无论nonpointer条件YES还是NO,最终返回的都是isa_t类型的isa。我们继续去看isa_t的定义。

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

    Class cls;
    uintptr_t bits;
#if defined(ISA_BITFIELD)
    struct {
        ISA_BITFIELD;  // defined in isa.h
    };
#endif
};
__arm64__
#   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 deallocating      : 1;                                       \
      uintptr_t has_sidetable_rc  : 1;                                       \
      uintptr_t extra_rc          : 19

ISA_BITFIELD中就是isa的数据结构定义。

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

isa与类关联

对象可以通过isa获取到类信息,cls 与 isa 关联原理就是isa指针中的shiftcls位域中存储了类信息,我们可以通过以下方式验证:
1.我们通过断点,通过lldb调试看newisa.shiftcls赋值前后newisa的变化

赋值前
(lldb) p newisa
(isa_t) $0 = {
  cls = 0x001d800000000001
  bits = 8303511812964353
   = {
    nonpointer = 1
    has_assoc = 0
    has_cxx_dtor = 0
    shiftcls = 0
    magic = 59
    weakly_referenced = 0
    deallocating = 0
    has_sidetable_rc = 0
    extra_rc = 0
  }
}

赋值后
(lldb) p newisa
(isa_t) $1 = {
  cls = LGPerson
  bits = 8303516107940081
   = {
    nonpointer = 1
    has_assoc = 0
    has_cxx_dtor = 0
    shiftcls = 536871966
    magic = 59
    weakly_referenced = 0
    deallocating = 0
    has_sidetable_rc = 0
    extra_rc = 0
  }
}

在newisa.shiftcls = (uintptr_t)cls >> 3这一步之后,cls变成了LGPerson,bits中也只有shiftcls发生了变化,说明类的信息存入了shiftcls中。
2.通过 isa & ISA_MSAK
注意:

  • arm64中,ISA_MASK 宏定义值0x0000000ffffffff8ULL
  • x86_64中,ISA_MASK 宏定义值0x00007ffff
    在_class_createInstanceFromZone方法中,initIsa之后
(lldb) po obj
<LGPerson: 0x100713e90>

(lldb) x/4gx obj
0x100713e90: 0x001d8001000020f1 0x0000000000000000
0x100713ea0: 0x72616553534e5b2d 0x20646c6569466863
(lldb) po 0x001d8001000020f1 & 0x0000000ffffffff8ULL
LGPerson

(lldb) 

相关文章

  • Cache_t的结构和原理

    在之间的文章里我们分析了isa的指向和结构isa结构分析,分析了bits类的结构分析,在这篇文章里,我们来分析ob...

  • iOS - isa的初始化&指向分析

    isa结构及初始化分析 什么是isa,首先我们先看一下isa的结构: 由源码我们可以看出:isa的本质就是一个联合...

  • isa结构分析

    什么是对象? 为了了解Objective-C类在底层会编译成什么,我们先新建一个类DebugPerson。 测试类...

  • isa结构分析

    isa结构分析 OC对象的本质 clang命令 把oc类编译成c++文件,对象在底层编译成struct 联合体(共...

  • isa结构分析

    OC对象的本质 在一个内中添加一个私有类,在main.m文件中添加一个LGPerson类 使用clang将main...

  • isa结构分析

    在我们iOS开发进行lldb调试的时候,经常会在控制台看到isa的存在,那么本文就来分析一下isa的结构。 在分析...

  • isa结构分析

    背景 书接上回alloc流程图分析中,在最后calloc分配空间,可得到空间的地址,那么calloc中系统是如何分...

  • ISA结构分析

    了解对象 Objective-C是一门面向对象编程语言。对象是什么,我们这篇文章讲的isa和对象又有什么样的关系呢...

  • isa结构分析

    在之前的文章OC对象的alloc过程中,我们探讨了OC对象初始化的主要过程,在第三步,主要是调用 initInst...

  • isa结构分析

    在对象调用alloc, 之后调用的最后一个方法是obj->initInstanceIsa, 它的作用是将isa指针...

网友评论

      本文标题:ISA结构分析

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