一、isa指针结构
union isa_t { isa_t() { } isa_t(uintptr_t value) : bits(value) { } Class cls; uintptr_t bits; #if SUPPORT_PACKED_ISA // extra_rc must be the MSB-most field (so it matches carry/overflow flags) // nonpointer must be the LSB (fixme or get rid of it) // shiftcls must occupy the same bits that a real class pointer would // bits + RC_ONE is equivalent to extra_rc + 1 // RC_HALF is the high bit of extra_rc (i.e. half of its range) // future expansion: // uintptr_t fast_rr : 1; // no r/r overrides // uintptr_t lock : 2; // lock for atomic property, @synch // uintptr_t extraBytes : 1; // allocated with extra bytes # if __arm64__ # define ISA_MASK 0x0000000ffffffff8ULL # define ISA_MAGIC_MASK 0x000003f000000001ULL # define ISA_MAGIC_VALUE 0x000001a000000001ULL struct { 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 struct { 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 // SUPPORT_PACKED_ISA #endif #if SUPPORT_INDEXED_ISA # if __ARM_ARCH_7K__ >= 2 # define ISA_INDEX_IS_NPI 1 # define ISA_INDEX_MASK 0x0001FFFC # define ISA_INDEX_SHIFT 2 # define ISA_INDEX_BITS 15 # define ISA_INDEX_COUNT (1 << ISA_INDEX_BITS) # define ISA_INDEX_MAGIC_MASK 0x001E0001 # define ISA_INDEX_MAGIC_VALUE 0x001C0001 struct { uintptr_t nonpointer : 1; uintptr_t has_assoc : 1; uintptr_t indexcls : 15; uintptr_t magic : 4; uintptr_t has_cxx_dtor : 1; uintptr_t weakly_referenced : 1; uintptr_t deallocating : 1; uintptr_t has_sidetable_rc : 1; uintptr_t extra_rc : 7; # define RC_ONE (1ULL<<25) # define RC_HALF (1ULL<<6) }; # else # error unknown architecture for indexed isa # endif // SUPPORT_INDEXED_ISA #endif };
分析:
1.我们知道,实例对象的isa指针指向该对象所属类的类对象;类对象的isa指向其元类对象;
2.真机为arm64架构,模拟器和mac电脑为x86架架构,以下以arm64为例讲解;
3.在64位系统下,指针所占字节为8个即64位;
4.在arm64之前,isa就是一个普通的指针,存放着类(元类)对象的地址;之后,则需要&
ISA_MASK掩码,才能获取到类(元类)对象的地址,此时isa指针为一个共用体,存储的信息不局限于类(元类)对象的地址;
5.存储信息介绍:
其中,shiftcls结构体成员变量(33位)用来存储类(元类)对象的地址;
二、类(元类)对象的地址取值原理——位域
1.结构体支持位域运算
//代码
struct bs { unsigned a : 9;//如果超过位域范围(511),则只取范围内的值,其他位(高位)丢弃 unsigned b : 4; unsigned c : 3; }bit, *pbit; void test1() { bit.a = 512;//超过位域范围报警告 bit.b = 10; bit.c = 7; NSLog(@"%d,%d,%d\n", bit.a, bit.b, bit.c); pbit=&bit; pbit-> a=0; pbit-> b&=3; pbit-> c|=1; printf("%d,%d,%d\n ",pbit-> a,pbit-> b,pbit-> c); }
//输