美文网首页
OC的isa指针存储了哪些信息?

OC的isa指针存储了哪些信息?

作者: 一叶知秋0830 | 来源:发表于2020-01-04 16:31 被阅读0次

OC中所有的实例对象、类对象和元类对象中都一个名为isa的成员变量,他们通常把它叫isa指针,既然是指针,那里面存储的应该就是一个地址。在以前的32位系统中,isa确实就是存储的一个地址,实例对象的isa存储的是其对应的类对象的地址,类对象的isa存储的是其对应的元类对象的地址,元类对象的isa存储的是根元类对象的地址。

但是在现在的64位系统(arm64架构)中,苹果对isa做了优化,里面除了存储一个地址外还存储了很多其他信息。一个指针占8个字节,也就是64位,苹果只用了其中的33位来存储地址,其余31位用来存储其他信息。下面我们来看下在arm64架构中关于isa的定义:

#   define ISA_MASK        0x0000000ffffffff8ULL
#   define ISA_MAGIC_MASK  0x000003f000000001ULL
#   define ISA_MAGIC_VALUE 0x000001a000000001ULL
#   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
#   define RC_ONE   (1ULL<<45)
#   define RC_HALF  (1ULL<<18)

上面信息中定义的像ISA_MASK这种常量我们不用管,这些都是程序在操作isa的过程中要用到的,比如我们将isaISA_MASK进行按位与运算isa & ISA_MASK就可以得到isa中存储的地址值。

我们主要关注一下uintptr_t类型数据:

  • nonpointer:(isa的第0位(isa的最后面那位),共占1位)。为0表示这个isa只存储了地址值,为1表示这是一个优化过的isa
  • has_assoc:(isa的第1位,共占1位)。记录这个对象是否是关联对象,没有的话,释放更快。
  • has_cxx_dtor:(isa的第2位,共占1位)。记录是否有c++的析构函数,没有的话,释放更快。
  • shiftcls:(isa的第3-35位,共占33位)。记录类对象或元类对象的地址值。
  • magic:(isa的第36-41位,共占6位),用于在调试时分辨对象是否完成初始化。
  • weakly_referenced:(isa的第42位,共占1位),用于记录该对象是否被弱引用或曾经被弱引用过,没有被弱引用过的对象可以更快释放。
  • deallocating:(isa的第43位,共占1位),标志对象是否正在释放内存。
  • has_sidetable_rc:(isa的第44位,共占1位),用于标记是否有扩展的引用计数。当一个对象的引用计数比较少时,其引用计数就记录在isa中,当引用计数大于某个值时就会采用sideTable来协助存储引用计数。
  • extra_rc:(isa的第45-63位,共占19位),用来记录该对象的引用计数值-1(比如引用计数是5的话这里记录的就是4)。这里总共是19位,如果引用计数很大,19位存不下的话就会采用sideTable来协助存储,规则如下:当19位存满时,会将19位的一半(也就是上面定义的RC_HALF)存入sideTable中,如果此时引用计数又+1,那么是加在extra_rc上,当extra_rc又存满时,继续拿出RC_HALF的大小放入sideTable。当引用计数减少时,如果extra_rc的值减少到了0,那就从sideTable中取出RC_HALF大小放入extra_rc中。综上所述,引用计数不管是增加还是减少都是在extra_rc上进行的,而不会直接去操作sideTable,这是因为sideTable中有个自旋锁,而引用计数的增加和减少操作是非常频繁的,如果直接去操作sideTable会非常影响性能,所以这样设计来尽量减少对sideTable的访问。

相关文章

  • OC的isa指针存储了哪些信息?

    OC中所有的实例对象、类对象和元类对象中都一个名为isa的成员变量,他们通常把它叫isa指针,既然是指针,那里面存...

  • iOS的内存管理

    一、引用计数值存储位置 OC对象的引用计数值存储在对象的isa指针中,isa的结构如下: 如果has_sideta...

  • IOS精选面试题(二)

    OC的实例对象,类对象和元类对象都分别存储了那些信息 实例对象包含了isa(32位就是一个指针,指向类对象,64位...

  • iOS:isa与superclass

    目录一,对象的三种类型二,对象的存储信息三,isa指针四,superclass指针五,isa和superclass...

  • Runtime - isa

    每一个oc对象内部都有一个isa指针。在arm64架构之前,isa就是一个普通的指针,存储着Class、Meta-...

  • OC 类&类结构分析

    OC底层原理学习 学习OC时,常听的就是万物皆对象,对象都有isa指针,那为什么有isa指针,isa指针到底是谁创...

  • Runtime之isa详解

    isa 概念 isa是相当于是OC对象的一个标识指针,只要是OC对象就一定会有isa指针,arm64之前isa就是...

  • 2-OC对象的分类

    OC对象分为三类 instance对象isa指针其他成员变量 class对象isa指针superclass指针协议...

  • iOS 底层解析-----RunTime 之 isa与Class

    之前文章有提到一个类的数据结构中存在着isa指针,本文将列出isa的结构,以及所存储的信息首先isa指针在内存中占...

  • iOS底层之类的重要组成部分-isa结构体分析

    前言 iOS中每个OC对象都有一个isa指针,那么这个isa指针又是什么呢,里面都有什么信息呢?接下来让我们一起探...

网友评论

      本文标题:OC的isa指针存储了哪些信息?

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