iOS底层原理--Runtime isa

runtime简介

运行时(Runtime)是指将数据类型的确定由编译时推迟到了运行时,Runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API,平时编写的OC代码,在程序运行过程中,其实最终会转换成Runtime的C语言代码,Runtime是Object-C的幕后工作者,Object-C会使用到Runtime来创建类和对象,进行消息发送和转发

特性: 编写的代码具有运行时、动态特性

isa
在我们初窥oc对象的时候了解到了isa,开始的时候我们感觉它像是一个C的指针,现在我们想要细致的了解iOS的运行时机制,我们需要更加细致的了解isa,对于我们了解runtime有很大的帮助。

arm64之前,isa只是一个指针,保存对象地址或者类对象地址,但是在arm64架构之后,苹果对isa进行了优化,变成了一个union结构,通过位域方式来存储更多的信息。

共用体:在进行某些算法的C语言编程的时候,需要使几种不同类型的变量存放到同一段内存单元中。也就是使用覆盖技术,几个变量互相覆盖。这种几个不同的变量共同占用一段内存的结构,在C语言中,被称作“共用体”类型结构,简称共用体。

先看下objc_object源码

我们知道OC对象的isa指针并不是直接指向类对象或者元类对象,而是需要&ISA_MASK通过位运算才能获取到类对象或者元类对象的地址。今天来探寻一下为什么需要&ISA_MASK才能获取到类对象或者元类对象的地址,以及这样的好处。源码中isa_t是union类型, 可以看到共用体中有一个结构体,结构体内部分别定义了一些变量,变量后面的值代表的是该变量占用多少个二进制位,也就是位域技术。

isa详解
要想学习Runtime,首先要了解它底层的一些常用数据结构,比如isa指针在arm64架构之前,isa就是一个普通的指针,存储着Class、Meta-Class对象的内存地址,从arm64架构开始,对isa进行了优化,变成了一个共用体(union)结构,还使用位域来存储更多的信息

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
};

# if __arm64__
#   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)

# elif __x86_64__
#   define ISA_MASK        0x00007ffffffffff8ULL
#   define ISA_MAGIC_MASK  0x001f800000000001ULL
#   define ISA_MAGIC_VALUE 0x001d800000000001ULL
#   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 deallocating      : 1;                                         \
      uintptr_t has_sidetable_rc  : 1;                                         \
      uintptr_t extra_rc          : 8
#   define RC_ONE   (1ULL<<56)
#   define RC_HALF  (1ULL<<7)

# else
#   error unknown architecture for packed isa
# endif

可以简化为下面的图


image.png

这里我们了解下每个字段的意义
nonpointer 代表iOS是普通的指针,存储着Class、Meta-Class对象的内存地址代表优化过,使用位域存储更多的信息
has_assoc 是否有设置过关联对象,如果没有,释放时会更快
has_cxx_dtor 是否有C++的析构函数(.cxx_destruct),如果没有,释放时会更快
shiftcls 存储着Class、Meta-Class对象的内存地址信息
magic 用于在调试时分辨对象是否未完成初始化
weakly_referenced 是否有被弱引用指向过,如果没有,释放时会更快
deallocating 对象是否正在释放
extra_rc 里面存储的值是引用计数器减1
has_sidetable_rc 引用计数器是否过大无法存储在isa中如果为1,那么引用计数会存储在一个叫SideTable的类的属性中

isa需求

isa取值

00000101
&00000100
·-------------
00000100
isa进行&操作,取哪位哪位值为1,结果有值相应位为1无值为0

补充“>>”代表左移 ,例“1>>0”左移0位 0b000001 值位1 ,“1>>1左移1位 0b000010 值位2

isa取值

使用||操作,和&操作
设置位赋值为1

设置位赋值为1,先安位取反 00000100 = ~111101111,在安位&,

取反产操作“~”

00000101
&11111011
·-------------
00000001

isa位域

    // 位域技术,利用了每个字节的每一位
    struct {
        char tall : 1; 
        char rich : 1;
        char handsome : 1;
    } _tallRichHandsome; 一个

补充共用体
在进行某些算法的C语言编程的时候,需要使几种不同类型的变量存放到同一段内存单元中。也就是使用覆盖技术,几个变量互相覆盖。这种几个不同的变量共同占用一段内存的结构,在C语言中,被称作“共用体”类型结构,简称共用体,也叫联合体,用isa举例子:isa所有数据都存在bits里面,下面的结构体是用于理解的

你可能感兴趣的:(iOS底层原理--Runtime isa)