iOS基礎:內(nèi)存管理-NSString相關知識

前言

本文主要講的是NSString類有關的內(nèi)存管理基礎知識。

正文

一达罗、面試常問的問題:為什么NSString的修飾詞常常是copy

這個問題雖然網(wǎng)上已經(jīng)有很多了坝撑,但是大多數(shù)都是字面上的解釋:為了防止mutable string被無意中修改, NSMutableString是NSString的子類, 因此NSString指針可以持有NSMutableString對象静秆。
這樣說確實難理解,最好的方法還是用例子來解釋巡李。
創(chuàng)建一個繼承NSObject的類抚笔,添加一個屬性:

@interface Model : NSObject
@property (nonatomic, copy) NSString *name;
@end

再回到控制器中,初始化類等操作:

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    Model *model = [Model new];
    NSString *str = @"sss";
    model.name = str;
    NSLog(@"str = %@, name = %@", str, model.name);
}

如果你只是進行上述代碼的操作侨拦,那么copy殊橙,strong都無所謂。但是狱从,如果你要這樣:

- (void)viewDidLoad
{
    [super viewDidLoad];

    Model *model = [Model new];
    NSMutableString *str = [[NSMutableString alloc] initWithString:@"sss"];
    model.name = str;
    [str appendString:@"aaa"];
    NSLog(@"str = %@, name = %@", str, model.name);
}

你會發(fā)現(xiàn)就有問題了膨蛮。
當你的修飾詞是strong時,輸出如下:
2017-03-13 16:22:58.338 MRCTest[58598:2227863] str = sssaaa, name = sssaaa
當修飾詞是copy時:
2017-03-13 16:20:51.681 MRCTest[58501:2225726] str = sssaaa, name = sss
也就是季研,當你的修飾詞為strong時敞葛,你的name屬性很可能在你不知情的情況下被篡改。但是為什么一個會隨之改變一個不會呢与涡,往下看惹谐。

二、為什么修飾詞為copy的屬性不會隨著改變

還是例子來說明:

    NSString *str = @"str";
    NSString *strCopy = [str copy];
    NSString *strMuCopy = [str mutableCopy];
    NSLog(@"str = %p, \nstrCopy = %p, \nstrMuCopy = %p", str, strCopy, strMuCopy);
    
    NSMutableString *muStr = [[NSMutableString alloc] initWithString:@"str"];
    NSMutableString *muStrCopy = [muStr copy];
    NSMutableString *muStrMuCopy = [muStr mutableCopy];
    NSLog(@"muStr = %p, \nmuStrCopy = %p, \nmuStrMuCopy = %p", muStr, muStrCopy, muStrMuCopy);

輸出:

    /*
     str = 0x10d501108,
     strCopy = 0x10d501108,
     strMuCopy = 0x600000264f40
     
     muStr = 0x608000266900,
     muStrCopy = 0xa000000007274733,
     muStrMuCopy = 0x608000264480
     */

從上面的例子可以看出:
1.當str不可變的時候驼卖,copy后地址不變(淺拷貝)氨肌,mutableCopy后地址改變(深拷貝)。
2.當str可變的時候款慨,不管copy或者mutableCopy都改變(深拷貝)儒飒。
地址一旦改變,也就意味著不會隨原來的str改變而改變了檩奠。

現(xiàn)在返回到第一大點:
如果給name賦值的屬性NSString桩了,也就是不可變的時候,copy為淺拷貝埠戳,所以和strong一樣井誉。
當給name賦值的屬性NSMutableString時候,如果是copy整胃,那么就會深拷貝颗圣,那么內(nèi)容不會隨之改變;如果是strong屁使,那么只是強引用在岂,地址仍然不變,所以會隨之改變了蛮寂。

另外蔽午,這里有需要注意的

實際上,不管是NSString或者NSMutableString酬蹋,只要調(diào)用copy及老,返回的都是NSString類型抽莱;相反,只要調(diào)用mutableCopy骄恶,返回的都是NSMutableString的食铐。
不信看這里:

    NSMutableString *muStr = [[NSMutableString alloc] initWithString:@"str"];
    NSMutableString *muStrCopy = [muStr copy];
    [muStrCopy appendString:@"111"];

運行結果為奔潰,原因就是muStrCopy找不到appendString方法僧鲁,因為muStrCopy的類型是NSString虐呻。

三、NSString不同的創(chuàng)建方法悔捶,不同的引用計數(shù)

1:

NSString *stringConst = @"str";

該方法引用計數(shù)為-1或unsigned int 2147483647铃慷,因為他是字符串常量单芜。

2:

[stringConst retain];

對于字符串常量來說蜕该,retain和release都是沒有用的,所以引用計數(shù)仍然為-1洲鸠。

3:

NSString *string1 = [NSString stringWithFormat:@"hello"];

如果是這種創(chuàng)建方法堂淡,string1的引用計數(shù)為1。

4:

NSString *string2 = [NSString stringWithString:stringConst];

如果是這種創(chuàng)建方法扒腕,得具體看stringConst類型绢淀,如果是字符串常量,那么引用計數(shù)仍然為-1瘾腰。

5:

NSString *string2 = [NSString stringWithString:string1];

如果是這種創(chuàng)建方法皆的,得具體看string1類型,如果string1有引用蹋盆,那么引用計數(shù)為+1费薄。
所以這里的引用計數(shù)為2

四、不可變字符串對象一旦被創(chuàng)建栖雾,就不能修改它

在網(wǎng)上看到這句話楞抡,覺得很奇怪。明明可以修改拔雠骸U偻ⅰ!
其實這樣的账胧,這句話的意思是創(chuàng)建好后竞慢,那個地址上的內(nèi)容不能變了。但是你可以指向另一個地址啊治泥。例子:
代碼:

    NSString *str = @"str1";
    NSLog(@"%p", str);
    str = @"str2";
    NSLog(@"%p", str);

結果:

2017-03-13 17:02:21.722 MRCTest[59226:2251613] 0x103811118
2017-03-13 17:02:21.723 MRCTest[59226:2251613] 0x103811158

可以看出筹煮,str分別指向@"str1"和@"str2",但是地址不同车摄,說明了指向地址已經(jīng)改變啦寺谤。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末仑鸥,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子变屁,更是在濱河造成了極大的恐慌眼俊,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件粟关,死亡現(xiàn)場離奇詭異疮胖,居然都是意外死亡,警方通過查閱死者的電腦和手機闷板,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門澎灸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人遮晚,你說我怎么就攤上這事性昭。” “怎么了县遣?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵糜颠,是天一觀的道長。 經(jīng)常有香客問我萧求,道長其兴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任夸政,我火速辦了婚禮元旬,結果婚禮上,老公的妹妹穿的比我還像新娘守问。我一直安慰自己匀归,他們只是感情好,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布酪碘。 她就那樣靜靜地躺著朋譬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪兴垦。 梳的紋絲不亂的頭發(fā)上徙赢,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天,我揣著相機與錄音探越,去河邊找鬼狡赐。 笑死,一個胖子當著我的面吹牛钦幔,可吹牛的內(nèi)容都是我干的枕屉。 我是一名探鬼主播,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼鲤氢,長吁一口氣:“原來是場噩夢啊……” “哼搀擂!你這毒婦竟也來了西潘?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤哨颂,失蹤者是張志新(化名)和其女友劉穎喷市,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體威恼,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡品姓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了箫措。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腹备。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖斤蔓,靈堂內(nèi)的尸體忽然破棺而出植酥,到底是詐尸還是另有隱情,我是刑警寧澤附迷,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布惧互,位于F島的核電站,受9級特大地震影響喇伯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拨与,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一稻据、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧买喧,春花似錦捻悯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至低淡,卻和暖如春姓言,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蔗蹋。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工何荚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人猪杭。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓餐塘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親皂吮。 傳聞我的和親對象是個殘疾皇子戒傻,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內(nèi)容