isa指針
在Objective-C中,實(shí)例對(duì)象的isa指向類對(duì)象,類對(duì)象的isa指向元類對(duì)象.其實(shí)這樣說是有一些不太嚴(yán)謹(jǐn)?shù)?應(yīng)該說在arm64架構(gòu)之前,isa就是一個(gè)普通的指針,存儲(chǔ)著Class,Meta-Class對(duì)象的內(nèi)存地址;但是在arm64架構(gòu)之后,對(duì)isa進(jìn)行了優(yōu)化,變成了一個(gè)共用體(union)結(jié)構(gòu).
蘋果提供的runtime源碼,查找 struct objec_object 里面的isa,下面我們研究的是arm64架構(gòu)的isa.
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)
};
我們發(fā)現(xiàn)isa的結(jié)構(gòu)是這種共用體(union)結(jié)構(gòu),使用這種共用體是一種優(yōu)化,isa存放的不再是單獨(dú)的一個(gè)指針信息了,里面存放了更多的其他信息.
基本概念
位運(yùn)算
- 左移 <<
- 右移 >>
- 按位或 |
- 按位與 &
- 按位取反 ~
- 按位異或 ^
位域
所謂位域是把一個(gè)字節(jié)中二進(jìn)制位劃分為幾個(gè)不同的區(qū)域,并說明每個(gè)區(qū)域的位數(shù).每個(gè)域有一個(gè)域名,允許在程序中按域名進(jìn)行操作.實(shí)際上是C語言提供的一種數(shù)據(jù)結(jié)構(gòu).
使用位域的好處是:
- 1.有些信息在存儲(chǔ)時(shí),并不需要占用一個(gè)完整的字節(jié),而只需占幾個(gè)或一個(gè)二進(jìn)制位.例如在存放一個(gè)開關(guān)量時(shí),只有0和1 兩種狀態(tài), 用一位二進(jìn)位即可.這樣節(jié)省存儲(chǔ)空間,而且處理簡便.這樣就可以把幾個(gè)不同的對(duì)象用一個(gè)字節(jié)的二進(jìn)制位域來表示.
- 2.可以很方便的利用位域把一個(gè)變量給按位分解.比如只需要4個(gè)大小在0到3的隨即數(shù),就可以只rand()一次,然后每個(gè)位域取2個(gè)二進(jìn)制位即可,省時(shí)省空間.
struct 位域結(jié)構(gòu)名 {位域列表};
struct {
char tall : 1;
char rich : 1;
char handsome : 1;
}_tallRichHandsome;
共用體
union中可以定義多個(gè)成員,union的大小由最大的成員的大小決定.
union成員共用同一塊大小的內(nèi)存空間,一次只能使用其中的一個(gè)成員
union中存放順序是從內(nèi)存的低地址往高地址存放
isa的結(jié)構(gòu)體
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)
};
說明:
1、nonpointer: 0 代表普通的指針,存儲(chǔ)著Class、Meta-Class對(duì)象的內(nèi)存地址; 1 代表優(yōu)化過,使用位域存儲(chǔ)更多的信息
2、has_assoc: 是否有設(shè)置過關(guān)聯(lián)對(duì)象,如果沒有,釋放時(shí)會(huì)更快
3、has_cxx_dtor: 是否有C++的析構(gòu)函數(shù)(.cxx_destruct),如果沒有,釋放時(shí)會(huì)更快
4、shiftcls: 存儲(chǔ)著Class、Meta-Class對(duì)象的內(nèi)存地址信息
5、magic: 用于在調(diào)試時(shí)分辨對(duì)象是否未完成初始化
6、weakly_referenced: 是否有被弱引用指向過,如果沒有,釋放時(shí)會(huì)更快
7、deallocating: 對(duì)象是否正在釋放
8、extra_rc: 里面存儲(chǔ)的值是引用計(jì)數(shù)器
9、has_sidetable_rc: 引用計(jì)數(shù)器是否過大無法存儲(chǔ)在isa中;如果為1,那么引用計(jì)數(shù)會(huì)存儲(chǔ)在一個(gè)叫SideTable的類的屬性中