ios內(nèi)存管理

目錄:

一楷兽、字符串(String)

1.1签孔、字符串的創(chuàng)建

1.2叉讥、字符串的isa

二、拷貝(copy)

2.1饥追、immutable對(duì)象的copy

2.2图仓、mutable對(duì)象的copy

2.3、淺拷貝與深拷貝

2.4 但绕、單層深拷貝

三救崔、 集合(Collections)

3.1、NSMapTable

3.2捏顺、NSHashTable

3.3六孵、NSPointerArray

一、字符串(String)

看到好幾篇文章都在說(shuō)這道面試題幅骄,字符串差不多是每個(gè)高級(jí)語(yǔ)言必有的劫窒,在實(shí)際項(xiàng)目中也的確是使用的最多類型之一。本文就以此題開(kāi)始我們的內(nèi)存管理的討論拆座。```
dsfdsl

//第一個(gè)

1.NSString *name1 = [NSString stringWithFormat:@"stringTestOne"];

__weak NSString *name2 = name1;

NSLog(@"name1:%@", name1);

NSLog(@"name2:%@", name2);

name1 = nil;

NSLog(@"name1:%@", name1);

NSLog(@"name2:%@", name2);

//第二個(gè)

NSString *a1 = [[NSString alloc] initWithFormat:@"stringTestTwo"];

__weak NSString *a2 = a1;

NSLog(@"a1:%@", a1);

NSLog(@"a2:%@", a2);

a1 = nil;

NSLog(@"a1:%@", a1);

NSLog(@"a2:%@", a2);

//第三個(gè)

NSString *b1 = @"stringTestThree";

__weak NSString *b2 = b1;

NSLog(@"b1:%@", b1);

NSLog(@"b2:%@", b2);

b1 = nil;

NSLog(@"b1:%@", b1);

NSLog(@"b2:%@", b2);

打印結(jié)果:

name1:stringTestOne

name2:stringTestOne

name1:(null)

name2:stringTestOne

a1:stringTestTwo

a2:stringTestTwo

a1:(null)

a2:(null)

b1:stringTestThree

b2:stringTestThree

b1:(null)

b2:stringTestThree

1.1主巍、字符串的創(chuàng)建

 NSString *string1 = [NSString stringWithFormat:@"TestString1_BAXIANG"];
    NSLog(@"%p",string1);
    NSString *string2 = [[NSString alloc] initWithFormat:@"TestString2_BAXIANG"];
    NSLog(@"%p",string2);
    NSString *string3 = @"TestString3_BAXIANG";
    NSLog(@"%p",string3);
打印結(jié)果:
 0x7fb6e7d58a40
 0x7fb6e7d1c3a0
 0x10e6a7280

(1) 關(guān)于stringWithFormat和initWithFormat的區(qū)別如果同學(xué)是從MRC開(kāi)發(fā)者一路過(guò)來(lái)的話理解這個(gè)很簡(jiǎn)單冠息,但是ARC已經(jīng)徹底主導(dǎo)了如今的開(kāi)發(fā),對(duì)引用計(jì)數(shù)這個(gè)概念不需要理解那么苛刻煤禽,stringWithFormat實(shí)際上創(chuàng)建的是一個(gè)加入自動(dòng)釋放池的 (autoreleased)的對(duì)象铐达,主要目的就是延遲釋放,而initWithFormat的對(duì)象就需要遵循我們常嘮叨的內(nèi)存管理黃金法則 誰(shuí)創(chuàng)建誰(shuí)釋放檬果。也就是MRC中的release瓮孙。

通過(guò)po _objc_autoreleasePoolPrint()打印當(dāng)前自動(dòng)釋放池的中對(duì)象(Autorelease pools),剛才我們通過(guò)stringWithFormat創(chuàng)建的字符串對(duì)象0x7fa65a50fdc0 在當(dāng)前釋放池中选脊。

objc[24294]: ##############
objc[24294]: AUTORELEASE POOLS for thread 0x10e6533c0
objc[24294]: 798 releases pending.
objc[24294]: [0x7fa65b800000]  ................  PAGE (full)  (cold)
objc[24294]: [0x7fa65b800038]  ################  POOL 0x7fa65b800038
objc[24294]: [0x7fa65b800040]    0x7fa65a702820  __NSCFString
objc[24294]: [0x7fa65b800048]  ################  POOL 0x7fa65b800048
........
// 
objc[24294]: [0x7fa65b010958]    0x7fa65a50fdc0  __NSCFString

所以第一個(gè)字符name1 = nil 只是去掉了對(duì)當(dāng)前0x7fa65a50fdc0 字符的指針杭抠。name2還是指向了0x7fa65a50fdc0字符串,所以name2還可以打印出當(dāng)前的字符數(shù)據(jù)恳啥。而關(guān)于通過(guò)打印內(nèi)存地址會(huì)發(fā)現(xiàn)字符串3(0x10e6a7280)會(huì)明顯小于上面二者偏灿,因?yàn)樗莿?chuàng)建在字符串常量區(qū)的,而我們的第一二字符串是創(chuàng)建在堆區(qū)的钝的。所以b2是照樣可以打印出字符串的翁垂。但是如果我們修改第二個(gè)字符串內(nèi)容為string,在64位的蘋(píng)果設(shè)備上調(diào)試硝桩,打印的結(jié)果變成跟我們的第一個(gè)和第二個(gè)字符串結(jié)果一樣的:

  NSString *a1 = [[NSString alloc] initWithFormat:@"string"];
    __weak NSString *a2 = a1;
    NSLog(@"a1:%@", a1);
    NSLog(@"a2:%@", a2);
    a1 = nil;
    NSLog(@"a1:%@", a1);
    NSLog(@"a2:%@", a2);
打印結(jié)果:
a1:string
a2:string
a1:(null)
a2:string
143845-ecbf28371592578a.png
143845-f3b6612ed88f7eab.png

我們只是縮短了字符串的長(zhǎng)度沿猜,當(dāng)前的字符串的類就變了 ,更讓人奇怪的是字符縮短后的對(duì)象沒(méi)有isa是空碗脊。也就是當(dāng)前字符串對(duì)象沒(méi)有類啼肩。這就涉及到apple的Tagged Pointer。

1.2字符串的isa

(1)NSTaggedPointerString

NSTaggedPointerString 用指針地址的富余位存儲(chǔ)當(dāng)前變量值衙伶,若對(duì)象指針的最低有效位為1(即奇數(shù))祈坠,則該指針為Tagged Pointer。這種指針不通過(guò)解引用isa來(lái)獲取其所屬類矢劲,而是通過(guò)接下來(lái)三位的一個(gè)類表的索引赦拘。該索引是用來(lái)查找所屬類是采用Tagged Pointer的哪個(gè)類。剩下的60位則存儲(chǔ)數(shù)據(jù)芬沉。對(duì)于NSNumber躺同,小于2^60-1的整數(shù)就都采用Tagged Pointer來(lái)存儲(chǔ),對(duì)于字符串來(lái)說(shuō)所需內(nèi)存小于60位的花嘶,它可以創(chuàng)建一個(gè)Tagged Pointer,所以NSTaggedPointerString是一個(gè)偽裝的對(duì)象蹦漠,里面存儲(chǔ)的不是指針地址而是字符串值椭员,這樣不需要一次真正對(duì)象的內(nèi)存分配,不需要一次間接取值笛园。同時(shí)引用計(jì)數(shù)可以是空指令隘击,因?yàn)闆](méi)有內(nèi)存需要釋放侍芝,所以會(huì)對(duì)性能有顯著的提升。

(2)__NSCFConstantString

字符串常量埋同,是一種編譯時(shí)常量州叠,它的 retainCount 值很大,在控制臺(tái)打印出的數(shù)值則是 18446744073709551615==2^64-1凶赁,測(cè)試證明咧栗,即便對(duì)其進(jìn)行 release 操作,retainCount 也不會(huì)產(chǎn)生任何變化虱肄。相同內(nèi)容的 NSCFConstantString 對(duì)象的地址相同致板,也就是說(shuō)常量字符串對(duì)象是一種單例。這種對(duì)象一般通過(guò)字面值 @"..."咏窿、CFSTR("...") 或者 stringWithString: 方法(需要說(shuō)明的是斟或,這個(gè)方法在 iOS6 SDK 中已經(jīng)被稱為redundant,使用這個(gè)方法會(huì)產(chǎn)生一條編譯器警告集嵌。這個(gè)方法等同于字面值創(chuàng)建的方法)產(chǎn)生萝挤。這種對(duì)象存儲(chǔ)在字符串常量區(qū)。

(3)NSCFString

對(duì)象被存儲(chǔ)在堆上根欧。 __NSCFString 對(duì)象是在運(yùn)行時(shí)創(chuàng)建的一種 NSString 子類怜珍,他并不是一種字符串常量。所以和其他的對(duì)象一樣在被創(chuàng)建時(shí)獲得了 1 的引用計(jì)數(shù)咽块。通過(guò) NSString 的 stringWithFormat 等方法創(chuàng)建的 NSString 對(duì)象一般都是這種類型绘面。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市侈沪,隨后出現(xiàn)的幾起案子揭璃,更是在濱河造成了極大的恐慌,老刑警劉巖亭罪,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瘦馍,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡应役,警方通過(guò)查閱死者的電腦和手機(jī)情组,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)箩祥,“玉大人院崇,你說(shuō)我怎么就攤上這事∨圩妫” “怎么了底瓣?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)蕉陋。 經(jīng)常有香客問(wèn)我捐凭,道長(zhǎng)拨扶,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任茁肠,我火速辦了婚禮患民,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘垦梆。我一直安慰自己匹颤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布奶赔。 她就那樣靜靜地躺著惋嚎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪站刑。 梳的紋絲不亂的頭發(fā)上另伍,一...
    開(kāi)封第一講書(shū)人閱讀 51,198評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音绞旅,去河邊找鬼摆尝。 笑死,一個(gè)胖子當(dāng)著我的面吹牛因悲,可吹牛的內(nèi)容都是我干的堕汞。 我是一名探鬼主播,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼晃琳,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼讯检!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起卫旱,我...
    開(kāi)封第一講書(shū)人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤人灼,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后顾翼,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體投放,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年适贸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了灸芳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡拜姿,死狀恐怖烙样,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蕊肥,我是刑警寧澤谒获,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響究反,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜儒洛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一精耐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧琅锻,春花似錦卦停、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至处硬,卻和暖如春小槐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背荷辕。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工凿跳, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人疮方。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓控嗜,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親骡显。 傳聞我的和親對(duì)象是個(gè)殘疾皇子疆栏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

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

  • 文章也同時(shí)在個(gè)人博客 http://kimihe.com/更新 引言 本文主要針對(duì)iOS內(nèi)存管理進(jìn)行總結(jié),相信看過(guò)...
    QihuaZhou閱讀 2,925評(píng)論 0 18
  • 以下內(nèi)容以至少你已經(jīng)理解OC內(nèi)萬(wàn)物皆對(duì)象的概念為基礎(chǔ),當(dāng)然你還得有一份可以跑得objc源碼 1. Obj befo...
    破弓閱讀 1,081評(píng)論 1 2
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉惫谤,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,709評(píng)論 0 9
  • 1. 內(nèi)總管理原則(引用計(jì)數(shù)) IOS的對(duì)象都繼承于NSObject, 該對(duì)象有一個(gè)方法:retainCount...
    lilinjianshu閱讀 2,156評(píng)論 0 2
  • Copyright ? 2017年ZaneWangWang. All rights reserved. 如果你看到...
    2897275c8a00閱讀 917評(píng)論 0 1