首先,從內存管理層面看:
普通對象都是存儲到堆內存上,而對於NSString對象:
NSString 初始化方法的內存方式比較
NSString *str1 = @"hello";
NSString *str2 = @"hello";
NSString *str3 = [NSString stringWithFormat:@"hello"];
NSString *str4 = [NSString stringWithString:@"hello"];
NSString *str5 = [[NSString alloc]initWithString:@"hello"];
NSLog(@"%p //%p //%p // %p //%p",str1,str2,str3,str4,str4,str5);
0x92a88 //0x92a88 //0x796b96b0 // 0x92a88 //0x92a88
SSting的對象在使用@"xx"直接初始化賦值時,它會在常量中分配一個空間,用於保存該變量。
(即存儲在內存裏的常量區而非堆區)
相同賦值的對象,會採用相同的內存空間,表現爲內存地址相同。
可以理解爲NSString的isa的值是一樣的。
NSString *str2=@"e中國2";
NSString *str3=@"e中國2";
// %p for pointers to show the memory address
NSLog(@"str2'addr is %p str3'addr is %p",str2,str3);
使用stringWithFormat:工廠方法初始化NSString對象時,每次都獨立分配內存空間。
這個空間是在堆區中,而不是常量區中。
即使相同內容的NSString對象,通過%d獲取的對象的內存地址的值不一致。
NSString *str2=[NSString stringWithFormat:@"e中國%i",2];
NSString *str3=[NSString stringWithFormat:@"e中國%i",2];
// %p for pointers to show the memory address
NSLog(@"str2'addr is %p str3'addr is %p",str2,str3);
NSString的比較方法,比較內容應該是isEqualToString:,比較指針的是==比較符號。通常情況下,你需要比較的都會是內容本身而不是其指針值
copy和mutable copy
1. copy出來的字符串一定是不可變字符串,如果傳入的是可變字符串,會發生深拷貝爲不可變字符串,否則爲淺拷貝。
2. mutablecopy,一定是深拷貝,拷貝出來的一定是可變字符串或者數組,即使傳入的是不可變字符串或者數組。
拓展:copy與mutableCopy對比
總的來說:
NSString *string = @"origion";
NSString *stringCopy = [string copy];
NSMutableString *stringMCopy = [string mutableCopy];
[stringMCopy appendString:@"!!"];
上面這段代碼中,需要注意的點:
1. retainCount對常量是無效的,數字會是個很大的數字。它對堆上的內存對象是正確的,對於 棧上的常量無效。
2. copy指的是淺複製,只是複製指針。(對可變的集合而言,copy是生成一個不可變對象。對 不可變的集合而言,copy等於strong,其中的元素都是淺拷貝)
3. mutableCopy是深複製,複製了對象到新的內存空間(對集合而言,mutableCopy是生成一個新的可變對象,其中的元素都是淺拷貝)
4. mutableCopy出來的都是可變的(如NSMutableString)