03-OC isa理解

251 阅读1分钟

引入

oc创建对象的时候回使用initInstanceIsa方法将内存和cls关联,其中也包括了初始化isa 那么obj和isa,类,指针地址关联起来的操作中,isa代表着什么?

每个类对象在内存中只存在一份,也就是上面的objClass1和objClass2是指向同一块内存。 类对象在内存中存储的信息包括:

  • isa指针
  • superClass指针
  • 类的属性信息(property)。非属性值,因为属性值只存储在实例对象当中,这里存储的是属性类型等
  • 类的对象方法信息(- (void)method)。
  • 类的协议信息(protocol)。
  • 类的成员变量信息(ivar)。

isa结构

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

isa_t结构的位域是一个宏ISA_BITFIELD 其中这个宏在不同的系统架构下的值不同

# 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

可以看出isa_t这里采用的是联合体&位域的搭配。 联合体有以下特点:

  • 联合体中可以定义多个成员,联合体的大小由最大的成员大小决定
  • 联合体的成员公用一个内存,一次只能使用一个成员
  • 对某一个成员赋值,会覆盖其他成员的值
  • 存储效率更高,可读性更强,可以提高代码的可读性,可以使用位运算提高数据的存储效率 所以苹果为了节省内存空间,这里使用了联合体的形式。

调试并验证

结论

对象在alloc的时候通过obj->initInstanceIsa(cls, hasCxxDtor);或obj->initIsa(cls);方法将 cls类 与 obj指针(即isa)关联。