NSSting 類族
NSSting 是一個(gè)類族(Class Clusters),最后生成的對(duì)象類型宗挥,取決于我們調(diào)用的初始化方法(Toll-free bridgin橋接機(jī)制 來實(shí)現(xiàn))
Toll-free bridgin橋接機(jī)制
Toll-free bridging,簡稱為TFB掰派,是一種允許某些ObjC類與其對(duì)應(yīng)的CoreFoundation類(Core Foundation框架 (CoreFoundation.framework) 是一組C語言接口从诲,它們?yōu)閕OS應(yīng)用程序提供基本數(shù)據(jù)管理和服務(wù)功能)之間可以互換使用的機(jī)制。比如 NSString與CFString是橋接(bridged)的, 這意味著可以將任意NSString當(dāng)做CFString使用靡羡,也可以將任意的CFString當(dāng)做NSString使用系洛。
原理(拿NSString舉例)大概是:NSString是一個(gè)抽象類,每當(dāng)你創(chuàng)建一個(gè)NSString實(shí)例亿眠,實(shí)際上是創(chuàng)建的NSString的一個(gè)私有子類實(shí)例碎罚。其中一個(gè)私有子類就是NSCFString,其是CFString類的在ObjC中的對(duì)應(yīng)類。NSCFString實(shí)現(xiàn)了作為NSString需要的所有方法纳像。
我的理解:總之荆烈,你知道有Toll-Free Bridging橋接機(jī)制,然后NSCFString是NSString的私有子類,實(shí)現(xiàn)了它的所有方法憔购。
NSSting 類型:
NSCFConstantString:常量類型宫峦,保存在常量區(qū),有時(shí)候也在棧區(qū)玫鸟,引用計(jì)數(shù)同樣為-1
NSCFString:堆區(qū)导绷, 引用計(jì)數(shù)同樣為 1
NSTaggedPointerString:優(yōu)化的NSCFString,引用計(jì)數(shù)同樣為-1
NSTaggedPointerString (0-9位是taggedpointer類型)
對(duì)于64位程序屎飘,為了節(jié)省內(nèi)存和提高運(yùn)行速度妥曲,蘋果引入了 Tagged Point 技術(shù)。
NSTaggedPointerString
是對(duì)NSCFString
優(yōu)化后的存在钦购,在運(yùn)行時(shí)創(chuàng)建時(shí)對(duì)字符串的內(nèi)容和長度做出判斷檐盟,若字符串內(nèi)容是由ASCII字符構(gòu)成且長度較小(大概十個(gè)字符以內(nèi))押桃,這時(shí)候創(chuàng)建的字符串就是NSTaggedPointerString
類型葵萎,字符串直接存儲(chǔ)在指針里,引用計(jì)數(shù)同樣為-1唱凯,不適用對(duì)象的內(nèi)存管理策略羡忘。
//類型=__NSCFConstantString, 地址=0x101d1a098
static NSString *a = @"a";
- (void)test {
//類型=__NSCFConstantString磕昼, 地址=0x101d1a0d8
NSString *a0 = @"aaa";
NSString *a1 = [[NSString alloc] init];
a0 = @"a0";
NSString *a2 = [[NSString alloc] initWithString:a0];
//類型=NSTaggedPointerString卷雕, 地址=0x89a6aa09cd52cc1f
NSString *a3 = [NSString stringWithFormat:@"%s", "str2"];
NSString *a4 = [NSString stringWithFormat:@"%d", 123];
NSString *a5 = [NSString stringWithFormat:@"%d", YES];
//類型=__NSCFString, 地址=0x60000032a5a0
NSString *a6 = [[NSString alloc] initWithFormat:@"aaa"];
//類型=__NSCFString票从, 地址=0x60000032a520爽蝴,
NSString *a7 = [NSString stringWithFormat:@"%@", @"aaa"];
//類型=NSTaggedPointerString, 地址=0x89a6aa09cd52cc1f
NSString *a8 = [NSString stringWithFormat:@"%@", a3];
//類型=__NSCFString纫骑, 地址=0x600000d70de0
NSMutableString *a9 = [NSMutableString stringWithFormat:@"%@", a0];
NSMutableString *a10 = [NSMutableString stringWithFormat:@"%@", a3];
NSMutableString *a11 = [NSMutableString stringWithFormat:@"%@", a6];
}
結(jié)論:
- 普通創(chuàng)建的字符串和
static
字符串都是NSCFConstantString
類型,如:a0 ~ a2九孩。- 使用
initWithFormat
方法創(chuàng)建先馆,參數(shù)為基礎(chǔ)數(shù)據(jù)類型(如:char
、bool
躺彬、int
等等)或NSTaggedPointerString
類型煤墙, 字符串都是NSTaggedPointerString
類型,如:a3~a5宪拥,a8仿野。- 使用
initWithFormat
方法創(chuàng)建,參數(shù)為對(duì)象類型的她君,字符串是NSCFString
類型脚作。如 a6~a7 和 a9 ~ a11
Tagged Pointer
Tagged Pointer
專門用來存儲(chǔ)小的對(duì)象,例如NSNumber
和NSDate
Tagged Pointer
指針地址保存的其實(shí)是(對(duì)象地址+值)。所以球涛,實(shí)際上它不再是一個(gè)對(duì)象了劣针,它只是一個(gè)披著對(duì)象皮的普通變量而已。所以亿扁,它的內(nèi)存并不存儲(chǔ)在堆中捺典,也不需要malloc
和free
。
在內(nèi)存讀取上有著3倍的效率从祝,創(chuàng)建時(shí)比以前快106倍襟己。
由此看來,NSTaggedPointerString
根本不是對(duì)象牍陌,是分配在棧區(qū)的
copy and mutableCopy
@property (nonatomic, strong) NSString *str;
@property (nonatomic, strong) NSString *str1;
@property (nonatomic, copy) NSString *str2;
@property (nonatomic, copy) NSString *str3;
- (void)test {
//類型=__NSCFConstantString擎浴, 地址=0x10ca08098
self.str = @"aaa";
self.str1 = self.str;
//str 類型=__NSCFConstantString, 地址=0x10ca08098
//str1 類型=__NSCFConstantString呐赡, 地址=0x10ca08138
self.str1 = @"bbb";
//類型=__NSCFConstantString退客, 地址=0x10ca08158
self.str2 = @"ccc";
self.str3 = self.str2;
//類型=__NSCFConstantString, 地址=0x10ca08158
//類型=__NSCFConstantString链嘀, 地址=0x10ca081b8
self.str3 = @"ddd";
}
- (void)test1 {
//類型=__NSCFConstantString萌狂, 地址=0x10ca08098
self.str = @"aaa";
self.str1 = [self.str copy];
//str 類型=__NSCFConstantString, 地址=0x10ca08098
//str1 類型=__NSCFConstantString怀泊, 地址=0x10ca08138
self.str1 = @"bbb";
//類型=__NSCFConstantString茫藏, 地址=0x10ca08158
self.str2 = @"ccc";
self.str3 = [self.str2 copy];
//類型=__NSCFConstantString, 地址=0x10ca08158
//類型=__NSCFConstantString霹琼, 地址=0x10ca081b8
self.str3 = @"ddd";
}
- (void)test2 {
//類型=__NSCFConstantString务傲, 地址=0x10ca08098
self.str = @"aaa";
//類型=__NSCFString, 地址=0x600003a60e70
self.str1 = [self.str mutableCopy];
//str 類型=__NSCFConstantString枣申, 地址=0x10ca08098
//str1 類型=__NSCFConstantString售葡, 地址=0x10b926138
self.str1 = @"bbb";
//類型=__NSCFConstantString, 地址=0x10ca08158
self.str2 = @"ccc";
//類型= NSTaggedPointerString忠藤, 地址=0xaec7592a59dc294c
self.str3 = [self.str2 mutableCopy];
//類型=__NSCFConstantString挟伙, 地址=0x10ca08158
//類型=__NSCFConstantString, 地址=0x10b9261b8
self.str3 = @"ddd";
}
總結(jié):
- 不管是
strong
還是copy
修飾字符串屬性模孩,使用=
賦值 和copy
都會(huì)出現(xiàn) swift 的寫時(shí)復(fù)制
的效果(而原來學(xué)習(xí)的時(shí)候尖阔,這2個(gè)關(guān)鍵字是深拷貝
和淺拷貝
的區(qū)別,估計(jì)是系統(tǒng)在新版本給做了優(yōu)化)榨咐。- 使用
mutableCopy
全部按照深拷貝
去實(shí)現(xiàn)介却。- 如果是局部變量,呈現(xiàn)的效果和屬性是一樣的块茁。