nsstring是乙個不可變的字串物件。這不是表示這個物件宣告的變數的值不可變,而是表示它初始化以後,你不能改變該變數所分配的記憶體中的值,但你可以重新分配該變數所處的記憶體空間。
生成乙個nsstring型別的字串有三種方法:
方法1.直接賦值: nsstring *str1 = @"my string";
方法2.類函式初始化生成: nsstring *str2 = [nsstring stringwithstring:@"my string"];
方法3.例項方法初始化生成: nsstring *str3 = [[nsstring alloc] initwithstring:@"my string"];
nsstring
*str4 = [[
nsstring
alloc
]initwithformat
:@"my string"];
區別1: 方法一生成字串時,不會初始化記憶體空間,所以使用結束後不會釋放記憶體;
而其他三個都會初始化記憶體空間,使用結束後要釋放記憶體;
在釋放記憶體時方法2和3也不同,方法2是autorelease型別,記憶體由系統釋放;方法3則必須手動釋放
區別2:用format初始化
的字串,需要初始化一段動態記憶體空間,如:
0x6a42a40;
而用string宣告的字串,初始化的是常量記憶體區,如:
0x46a8
,常量記憶體區的位址,只要值相同,占用的位址空間是一致的。
所以str3和str1的位址一致,但是str4和str1的位址不一致。
前幾天去面試,被問到了nsstring屬性宣告中的copy和retain具體區別,對記憶體計數的影響,汗,當時沒整明白,也沒答出來,只知道nsstring一般用copy.
首先做以下幾個變數宣告:
@property (retain, nonatomic) nsstring *retainstr;
@property (copy, nonatomic) nsstring *copystr;
@property (retain, nonatomic) nsmutablestring *retainmstr;
@property (copy, nonatomic) nsmutablestring *copymstr;
實現**如下:
nsmutablestring *mstr = [nsmutablestring string];
[mstr setstring:@"我沒變"];
self.retainstr = mstr;
self.copystr = mstr;
self.retainmstr = mstr;
self.copymstr = mstr;
nslog(@"retainstr:%@", self.retainstr);
nslog(@"copystr:%@", self.copystr);
nslog(@"retainmstr:%@", self.retainmstr);
nslog(@"copymstr:%@", self.copymstr);
nslog(@"\n");
[mstr setstring:@"我變了"];
nslog(@"retainstr:%@", self.retainstr);
nslog(@"copystr:%@", self.copystr);
nslog(@"retainmstr:%@", self.retainmstr);
nslog(@"copymstr:%@", self.copymstr);
nslog(@"\n");
nsstring *str = @"我來了";//[[nsstring alloc] initwithformat:@"我來了"];//兩種方式都一樣。
self.retainstr = str;
self.copystr = str;
self.retainmstr = [str mutablecopy];
self.copymstr = [str mutablecopy];
nslog(@"retainstr:%@", self.retainstr);
nslog(@"copystr:%@", self.copystr);
nslog(@"retainmstr:%@", self.retainmstr);
nslog(@"copymstr:%@", self.copymstr);
nslog(@"\n");
str =@"我走了";//[[nsstringalloc] initwithformat:@"我走了"];//兩種方式都一樣
nslog(@"retainstr:%@", self.retainstr);
nslog(@"copystr:%@", self.copystr);
nslog(@"retainmstr:%@", self.retainmstr);
nslog(@"copymstr:%@", self.copymstr);
nslog(@"\n");
列印結果如下:
2012-10-12 13:53:14.858 stringdemo[1515:11303] retainstr:我沒變
2012-10-12 13:53:14.860 stringdemo[1515:11303] copystr:我沒變
2012-10-12 13:53:14.861 stringdemo[1515:11303] retainmstr:我沒變
2012-10-12 13:53:14.862 stringdemo[1515:11303] copymstr:我沒變
2012-10-12 13:53:14.863 stringdemo[1515:11303]
2012-10-12 13:53:14.864 stringdemo[1515:11303] retainstr:我變了
2012-10-12 13:53:14.865 stringdemo[1515:11303] copystr:我沒變
2012-10-12 13:53:14.866 stringdemo[1515:11303] retainmstr:我變了
2012-10-12 13:53:14.867 stringdemo[1515:11303] copymstr:我沒變
2012-10-12 13:53:14.868 stringdemo[1515:11303]
2012-10-12 13:53:14.869 stringdemo[1515:11303] retainstr:我來了
2012-10-12 13:53:14.869 stringdemo[1515:11303] copystr:我來了
2012-10-12 13:53:14.870 stringdemo[1515:11303] retainmstr:我來了
2012-10-12 13:53:14.871 stringdemo[1515:11303] copymstr:我來了
2012-10-12 13:53:14.872 stringdemo[1515:11303]
2012-10-12 13:53:14.873 stringdemo[1515:11303] retainstr:我來了
2012-10-12 13:53:14.874 stringdemo[1515:11303] copystr:我來了
2012-10-12 13:53:14.875 stringdemo[1515:11303] retainmstr:我來了
2012-10-12 13:53:14.876 stringdemo[1515:11303] copymstr:我來了
由此可以看出:對源頭是nsmutablestring的字串,retain僅僅是指標引用,增加了引用計數器,這樣源頭改變的時候,用這種retain方式宣告的變數(無論被賦值的變數是可變的還是不可變的),它也會跟著改變;而copy宣告的變數,它不會跟著源頭改變,它實際上是深拷貝。對源頭是nsstring的字串,無論是retain宣告的變數還是copy宣告的變數,當第二次源頭的字串重新指向其它的地方的時候,它還是指向原來的最初的那個位置,也就是說其實二者都是指標引用,也就是淺拷貝。
另外說明一下,這兩者對記憶體計數的影響都是一樣的,都會增加記憶體引用計數,都需要在最後的時候做處理。
其實說白了,對字串為啥要用這兩種方式?我覺得還是乙個安全問題,比如宣告的乙個nsstring *str變數,然後把乙個nsmutablestring *mstr變數的賦值給它了,如果要求str跟著mstr變化,那麼就用retain;如果str不能跟著mstr一起變化,那就用copy。而對於要把nsstring型別的字串賦值給str,那兩都沒啥區別。不會影響安全性,記憶體管理也一樣。
NSString的記憶體管理問題
nsstring是乙個不可變的字串物件。這不是表示這個物件宣告的變數的值不可變,而是表示它初始化以後,你不能改變該變數所分配的記憶體中的值,但你可以重新分配該變數所處的記憶體空間。生成乙個nsstring型別的字串有三種方法 方法1.直接賦值 nsstring str1 my string 方法2....
NSString的記憶體實現
nsstring等foundation框架提供的類的記憶體管理 1 字串的常量池 在資料區 2 nsstring str1 abc nsstring str2 nsstring stringwithstring abc nsstring str3 nsstring alloc initwithstr...
NSString中的數字問題
在寫學生管理系統的時候,需要判斷student類中 學生姓名中是否有數字,學號 年齡 成績是否全為數字,而在定義時把它們都設為了nsstring,所以需要從nsstring中提取出,或判斷出數字。用於判斷學生姓名 用來判斷姓名和班級 是否含有數字 nscharacterset characterse...