-
Tagged Pointer
從 5s 開始制跟,iPhone 均使用 arm64 指令集的處理器思币。在 64 位系統(tǒng)上彬向,一個(gè)指針占 8 個(gè)字節(jié),而指針指向的實(shí)例變量至少需要 16 個(gè)字節(jié)空郊,并且還需要執(zhí)行額外的一些操作,例如:申請內(nèi)存切揭,銷毀內(nèi)存狞甚。為了達(dá)到優(yōu)化的目的,蘋果將一些存儲(chǔ)數(shù)據(jù)的類廓旬,例如 NSString哼审,NSNumber,當(dāng)它們需要保存的數(shù)據(jù)不需要占用那么多的字節(jié)時(shí)孕豹,直接將數(shù)據(jù)保存在“指針”里面涩盾。
enum
#endif
{
// 60-bit payloads
OBJC_TAG_NSAtom = 0,
OBJC_TAG_1 = 1,
OBJC_TAG_NSString = 2,
OBJC_TAG_NSNumber = 3,
OBJC_TAG_NSIndexPath = 4,
OBJC_TAG_NSManagedObjectID = 5,
OBJC_TAG_NSDate = 6,
// 60-bit reserved
OBJC_TAG_RESERVED_7 = 7,
// 52-bit payloads
OBJC_TAG_Photos_1 = 8,
OBJC_TAG_Photos_2 = 9,
OBJC_TAG_Photos_3 = 10,
OBJC_TAG_Photos_4 = 11,
OBJC_TAG_XPC_1 = 12,
OBJC_TAG_XPC_2 = 13,
OBJC_TAG_XPC_3 = 14,
OBJC_TAG_XPC_4 = 15,
OBJC_TAG_NSColor = 16,
OBJC_TAG_UIColor = 17,
OBJC_TAG_CGColor = 18,
OBJC_TAG_NSIndexSet = 19,
OBJC_TAG_First60BitPayload = 0,
OBJC_TAG_Last60BitPayload = 6,
OBJC_TAG_First52BitPayload = 8,
OBJC_TAG_Last52BitPayload = 263,
OBJC_TAG_RESERVED_264 = 264
};
NSString *str = [NSString stringWithFormat:@"%@",@"fffff"];
NSNumber *a1 = [NSNumber numberWithInt:2];
NSLog(@"str - %lx",((uintptr_t)str ^ objc_debug_taggedpointer_obfuscator));
NSLog(@"a - %lx",((uintptr_t)a ^ objc_debug_taggedpointer_obfuscator));
打印結(jié)果:
str - 'a000066666666665'
a - 'b000000000000022'
str
指針中a
轉(zhuǎn)成二進(jìn)制為1010
,最高位的1
標(biāo)識tagged pointer
励背;010
為2
,由上面的枚舉值可知是OBJC_TAG_NSString
,標(biāo)識字符串旁赊;最低位5
則標(biāo)識字符串個(gè)數(shù)(number類型最低位標(biāo)識值類型,2椅野、4、5籍胯、3
分別代表int long float double
),中間位則用來存儲(chǔ)數(shù)值
Tagged Pointer
的引用主要解決內(nèi)存浪費(fèi)和訪問效率的問題竟闪。所以其有以下特點(diǎn):
1、Tagged Pointer
專門用于存儲(chǔ)小的對象杖狼,例如:NSString
炼蛤、NSNumber
和NSDate
。
2蝶涩、Tagged Pointer
指針的值不再是堆區(qū)地址理朋,而是真正的值。所以绿聘,實(shí)際上它不再是一個(gè)對象了嗽上,它只是一個(gè)披著對象皮的普通變量而已。所以熄攘,它的內(nèi)存并不存儲(chǔ)在堆中兽愤,也不需要malloc
和free
。
3挪圾、在內(nèi)存讀取上有著3 倍
的效率浅萧,創(chuàng)建時(shí)比以前快106 倍
由此可見,蘋果引入Tagged Pointer哲思,不但減少了 64 位機(jī)器下程序的內(nèi)存占用洼畅,還提高了運(yùn)行效率。完美地解決了小內(nèi)存對象在存儲(chǔ)和訪問效率上的問題棚赔。
-
引用計(jì)數(shù)
黃金法則
- 自己生成的對象帝簇,自己持有
- 非自己生成的對象徘郭,自己也能持有
- 不在需要自己持有對象的時(shí)候,釋放
- 非自己持有的對象無需釋放
拓展
- 野指針己儒、僵尸對象崎岂、空指針
當(dāng)一個(gè)指針變量p指向一個(gè)對象obj的地址空間,則稱p持有obj闪湾,obj的引用計(jì)數(shù)+1,當(dāng)obj引用計(jì)數(shù)為0被釋放冲甘,則p不再持有obj,如果obj不被銷毀途样,則p就叫做野指針江醇,obj叫做僵尸對象,如果將obj銷毀何暇,則p不指向任何內(nèi)存地址陶夜,p叫做空指針