在本章中,我們從NSObject的定義出發(fā)隘截,了解了OC中類(lèi)和對(duì)象所對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)objc_class和objc_object扎阶。關(guān)于NSObject事富,objc_class和objc_object三者之間的關(guān)系,我們可以用下面的圖來(lái)更清晰的了解:
其實(shí) isa_t 是一個(gè)定義得非常"奇怪"的結(jié)構(gòu)體乘陪,在 ObjC 源代碼中可以看到這樣的定義:
#define?ISA_MASK??????0x00007ffffffffff8ULL
#define?ISA_MAGIC_MASK??0x001f800000000001ULL
#define?ISA_MAGIC_VALUE?0x001d800000000001ULL
#define?RC_ONE???(1ULL<<56)
#define?RC_HALF??(1ULL<<7)
union?isa_t?{
????isa_t()?{?}
????isa_t(uintptr_t?value)?:?bits(value)?{?}
????Class?cls;
????uintptr_t?bits;
????struct?{
????????uintptr_t?indexed???????????:?1;
????????uintptr_t?has_assoc?????????:?1;
????????uintptr_t?has_cxx_dtor??????:?1;
????????uintptr_t?shiftcls??????????:?44;
????????uintptr_t?magic?????????????:?6;
????????uintptr_t?weakly_referenced?:?1;
????????uintptr_t?deallocating??????:?1;
????????uintptr_t?has_sidetable_rc??:?1;
????????uintptr_t?extra_rc??????????:?8;
????};
};
這是在 __x86_64__ 上的實(shí)現(xiàn),對(duì)于 iPhone5s 等架構(gòu)為 __arm64__ 的設(shè)備上雕擂,具體結(jié)構(gòu)體的實(shí)現(xiàn)和位數(shù)可能有些差別啡邑,不過(guò)這些字段都是存在的,可以看這里的arm64 上結(jié)構(gòu)體的實(shí)現(xiàn)井赌。
在本篇文章中, 我們會(huì)以 __x86_64__ 為例進(jìn)行分析谤逼,而不會(huì)對(duì)兩種架構(gòu)下由于不同的內(nèi)存布局方式導(dǎo)致的差異進(jìn)行分析。在我看來(lái)仇穗,這個(gè)細(xì)節(jié)不會(huì)影響對(duì) isa 指針的理解流部,不過(guò)還是要知道的。
筆者對(duì)這個(gè) isa_t 的實(shí)現(xiàn)聲明順序有一些更改纹坐,更方便分析和理解枝冀。
union?isa_t?{
????...
};
isa_t 是一個(gè) union 類(lèi)型的結(jié)構(gòu)體,對(duì) union 不熟悉的讀者可以看這個(gè) stackoverflow 上的回答耘子。也就是說(shuō)其中的 isa_t果漾、cls、 bits 還有結(jié)構(gòu)體共用同一塊地址空間谷誓。而 isa 總共會(huì)占據(jù) 64 位的內(nèi)存空間(決定于其中的結(jié)構(gòu)體)
struct?{
???uintptr_t?indexed???????????:?1;
???uintptr_t?has_assoc?????????:?1;
???uintptr_t?has_cxx_dtor??????:?1;
???uintptr_t?shiftcls??????????:?44;
???uintptr_t?magic?????????????:?6;
???uintptr_t?weakly_referenced?:?1;
???uintptr_t?deallocating??????:?1;
???uintptr_t?has_sidetable_rc??:?1;
???uintptr_t?extra_rc??????????:?8;
};
在 isa_t 中绒障,我們還有一些沒(méi)有介紹的其它 bits,在這個(gè)小結(jié)就簡(jiǎn)單介紹下這些 bits 的作用
has_assoc:對(duì)象含有或者曾經(jīng)含有關(guān)聯(lián)引用捍歪,沒(méi)有關(guān)聯(lián)引用的可以更快地釋放內(nèi)存
weakly_referenced:對(duì)象被指向或者曾經(jīng)指向一個(gè) ARC 的弱變量户辱,沒(méi)有弱引用的對(duì)象可以更快釋放
deallocating:對(duì)象正在釋放內(nèi)存
has_sidetable_rc:對(duì)象的引用計(jì)數(shù)太大了,存不下
extra_rc:對(duì)象的引用計(jì)數(shù)超過(guò) 1糙臼,會(huì)存在這個(gè)這個(gè)里面庐镐,如果引用計(jì)數(shù)為 10,extra_rc 的值就為 9
從 NSObject 的初始化了解 isa