對象的本質
objc_object結構體,??存儲isa指針和成員變量的值
class_getInstanceSize:實際占用的內存空間
malloc_size:系統(tǒng)開辟的內存空間
sizeof:變量的內存大?。惣粗羔槾笮?,結構體即結構體大小)
OSTestObject1 *objc1 = [[OSTestObject1 alloc] init];
?objc1->count=10;
(lldb) x/6gx objc1
0x6000006718a0: 0x0000000101fdc660 0x0000000000000000
0x6000006718b0: 0x0000000000000000 0x000000000000000a
0x6000006718c0: 0x0000000000000000 0x0000000000000000
0x000000000000000a 存count的值
對象??存儲了?個isa指針?+?成員變量的值,isa指針是固定的,占8個字節(jié),所以影響對象內存的只有成員變量(屬性會?動?成帶下劃線的成員變量)。在對象的內部是以8字節(jié)進?對?的。蘋果會?動重成員變量的順序,將占?不??8?字節(jié)的成員挨在?起,湊滿?8?字節(jié),以達到優(yōu)化內存的?的。
isa指針探索
聯合體和結構體
結構體(struct)中所有變量是“共存”的,?聯合體(union)中是各變量是“互斥”的,只能存在?個。struct內存空間的分配是粗放的,不管?不?,全部分配。這樣帶來的?個壞處就是對于內存的消耗要??些。但是結構體??的數據是完整的。聯合體??的數據只能存在?個,但優(yōu)點是內存使?更為精細靈活,也節(jié)省了內存空間。
位域
位域的寬度不能超過前?數據類型的最??度,?如int占4個字節(jié)也就是32位,那后?的數字就不能超過32。?個位域存儲在同?個字節(jié)中,如?個字節(jié)所??臻g不夠存放另?位域時,則會從下?單元起存放該位域。位域能夠節(jié)省?定的內存空間
[xxx alloc] 最后調用?_class_createInstanceFromZone,查看源碼
初始化isa 指針 obj->initIsa(cls);
objc_object::initIsa(Class cls)
{
? ? initIsa(cls,false,false);
}
是一個?Class 類型?
typedef struct objc_class *Class;
struct objc_class : objc_object
Class是一個對象,因為繼承objc_object
objc_object 存在?isa_t isa;
union isa_t {
????isa_t() { }
? ? isa_t(uintptr_tvalue) :bits(value) { }
? ? uintptr_tbits;
...
? ??public:
#if defined(ISA_BITFIELD)
? ? struct{
? ? ? ? ISA_BITFIELD;? // defined in isa.h
? ? };
...
#endif
}
ISA_BITFIELD分平臺的
arm64?(真機) 位域
uintptr_t nonpointer : 1;
uintptr_t has_assoc : 1;
uintptr_t has_cxx_dtor : 1;
uintptr_t shiftcls : 33;
uintptr_t magic : 6;
uintptr_t weakly_referenced : 1;
uintptr_t unused : 1;
uintptr_t has_sidetable_rc : 1;
uintptr_t extra_rc : 19
isa_t聯合體大小是8個字節(jié)
nonPointerIsa
nonPointerIsa是內存優(yōu)化的?種?段。isa是?個Class類型的結構體指針,占8個字節(jié),主要是?來存內存地址的。但是8個字節(jié)意味著它就有8*8=64位。存儲地址根本不需要這么多的內存空間。?且每個對象都有個isa指針,這樣就浪費了內存。所以蘋果就把和對象?些息息相關的東?,存在了這塊內存空間??。這種isa指針就叫nonPointerIsa。