引入
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)关联。