簡單描述iOS的內(nèi)存管理

一、為什么要管理內(nèi)存

  • 由于移動(dòng)設(shè)備的內(nèi)存極其有限,所以每個(gè)APP所占的內(nèi)存也是有限制的,當(dāng)app所占用的內(nèi)存較多時(shí)帆谍,系統(tǒng)就會(huì)發(fā)出內(nèi)存警告,這時(shí)需要回收一些不需要再繼續(xù)使用的內(nèi)存空間轴咱,比如回收一些不再使用的對(duì)象和變量等汛蝙。
  • iOS應(yīng)用程序出現(xiàn)Crash(閃退), 90%的原因是內(nèi)存管理問題烈涮。
  • 當(dāng)一個(gè)有十幾個(gè)或者幾十個(gè)類的工程中, 查找內(nèi)存問題是非常難的一件事, 所以一定要學(xué)好內(nèi)存管理, 這個(gè)很重要患雇。

二跃脊、內(nèi)存的管理范圍

  • 任何繼承NSObject的對(duì)象,對(duì)其他的基本數(shù)據(jù)類型無效苛吱。

三酪术、內(nèi)存管理的錯(cuò)誤方式

  • 內(nèi)存溢出和野指針異常
    (1) 內(nèi)存溢出
    內(nèi)存過多導(dǎo)致溢出, 導(dǎo)致Crash
    (2) 野指針 (過度釋放)
    指針指向未知的區(qū)域, 就是指針指向一塊被釋放的區(qū)域

四、內(nèi)存管理方式

(1) 垃圾回收機(jī)制: 程序員只需要開辟內(nèi)存, 而不需要以代碼的形式管理內(nèi)存, 系統(tǒng)會(huì)自動(dòng)判斷這部分內(nèi)存是否需要釋放翠储。(iOS不支持垃圾回收)
(2) MRC(Manual Reference Counting): 手動(dòng)管理引用計(jì)數(shù)
(3) ARC(Auto Reference Counting): 自動(dòng)管理引用計(jì)數(shù)(現(xiàn)在常用)
注意: ARC基于MRC進(jìn)行管理, 系統(tǒng)幫程序員添加了內(nèi)存管理的內(nèi)容

五绘雁、內(nèi)存管理--引用計(jì)數(shù)

在OC中每個(gè)對(duì)象內(nèi)部都有一個(gè)與之對(duì)應(yīng)的整數(shù)(retainCount),叫“引用計(jì)數(shù)器”
有retain, alloc, copy 會(huì)對(duì)引用計(jì)數(shù)加1
有release, autorelease 會(huì)對(duì)引用計(jì)數(shù)減1
當(dāng)對(duì)象的計(jì)數(shù)器為0的時(shí)候, 系統(tǒng)會(huì)調(diào)用對(duì)應(yīng)的dealloc方法
注意: 內(nèi)存管理, 你對(duì)對(duì)象操作完成后, 再進(jìn)行釋放

Man *man = [[Man alloc] init];
NSLog(@"%ld", man.retainCount);
[man retain];
[man release];
NSLog(@"%ld--%@", man.retainCount, man);

集合類型, 會(huì)對(duì)對(duì)象進(jìn)行引用計(jì)數(shù)
addObject 對(duì) 對(duì)象進(jìn)行引用計(jì)數(shù)加1
removeObject 對(duì) 對(duì)象進(jìn)行引用計(jì)數(shù)減1

NSMutableArray *arr = [NSMutableArray arrayWithObjects:man, nil];
NSLog(@"向數(shù)組中添加后的引用計(jì)數(shù) %ld", man.retainCount);
[arr removeAllObjects];
NSLog(@"從數(shù)組中移除后的引用計(jì)數(shù) %ld", man.retainCount);

六援所、ARC(自動(dòng)管理引用計(jì)數(shù))

  • 怎樣關(guān)閉ARC進(jìn)入MRC模式?


    關(guān)閉ARC.png

如上圖所示, 將YES改為NO即為關(guān)閉ARC進(jìn)入MRC模式

  • 如果需要對(duì)特定文件開啟或關(guān)閉ARC庐舟,可以在工程選項(xiàng)中選擇BuildPhases -> Compile Sources,在里面找到對(duì)應(yīng)文件住拭,雙擊后添加flag:
    打開ARC:-fobjc-arc
    關(guān)閉ARC:-fno-objc-arc
    如圖所示, 為關(guān)閉ViewController的ARC, 如果需要打開ARC, 則輸入-fobjc-arc


    打開或者關(guān)閉特定文件的ARC
ARC主要提供了4種修飾符挪略,他們分別是:__strong, __weak, __autoreleasing, __unsafe_unretained。
(1)__strong

表示引用為強(qiáng)引用在ARC下使用, 引用計(jì)數(shù)加1滔岳。對(duì)應(yīng)在定義property時(shí)的"strong"杠娱。所有對(duì)象只有當(dāng)沒有任何一個(gè)強(qiáng)引用指向時(shí),才會(huì)被釋放谱煤。
注意:如果在聲明引用時(shí)不加修飾符摊求,那么引用將默認(rèn)是強(qiáng)引用。當(dāng)需要釋放強(qiáng)引用指向的對(duì)象時(shí)刘离,需要將強(qiáng)引用置nil室叉。

(2)__weak

表示引用為弱引用。對(duì)應(yīng)在定義property時(shí)用的"weak"硫惕。弱引用不會(huì)影響對(duì)象的釋放茧痕,即只要對(duì)象沒有任何強(qiáng)引用指向,即使有100個(gè)弱引用對(duì)象指向也沒用恼除,該對(duì)象依然會(huì)被釋放踪旷。不過好在,對(duì)象在被釋放的同時(shí)缚柳,指向它的弱引用會(huì)自動(dòng)被置nil,這個(gè)技術(shù)叫zeroing weak pointer搪锣。這樣有效得防止無效指針秋忙、野指針的產(chǎn)生。

定義一個(gè)__weak類型的正確方式和錯(cuò)誤方式

NSString * __weak str = @"hehe"; // 正確构舟!
__weak NSString *str = @"hehe";  // 錯(cuò)誤灰追!
(3)__autoreleasing

表示在autorelease pool中自動(dòng)釋放對(duì)象的引用,和MRC時(shí)代autorelease的用法相同。定義property時(shí)不能使用這個(gè)修飾符弹澎,任何一個(gè)對(duì)象的property都不應(yīng)該是autorelease型的朴下。

NSString *str = [[[NSString alloc] initWithFormat:@"hehe"] autorelease]; // MRC下
NSString *__autoreleasing str = [[NSString alloc] initWithFormat:@"hehe"]; // ARC下
(4)__unsafe_unretained

ARC是在iOS 5引入的,而這個(gè)修飾符主要是為了在ARC剛發(fā)布時(shí)兼容iOS 4以及版本更低的設(shè)備苦蒿,因?yàn)檫@些版本的設(shè)備沒有weak pointer system殴胧,簡單的理解這個(gè)系統(tǒng)就是我們上面講weak時(shí)提到的,能夠在weak引用指向?qū)ο蟊会尫藕笈宄伲岩弥底詣?dòng)設(shè)為nil的系統(tǒng)团滥。這個(gè)修飾符在定義property時(shí)對(duì)應(yīng)的是"unsafe_unretained",實(shí)際可以將它理解為MRC時(shí)代的assign:純粹只是將引用指向?qū)ο蟊ㄇ浚瑳]有任何額外的操作灸姊,在指向?qū)ο蟊会尫艜r(shí)依然原原本本地指向原來被釋放的對(duì)象(所在的內(nèi)存區(qū)域)。所以非常不安全秉溉。

七力惯、MRC(手動(dòng)引用計(jì)數(shù))

在這個(gè)模式下使用alloc、new召嘶、copy創(chuàng)建一個(gè)對(duì)象父晶,該對(duì)象的retainCount都等于1,需要用release來釋放該對(duì)象苍蔬。就是誰創(chuàng)建的诱建,誰就去釋放。

如果你定義了一個(gè)屬性(刨除assign修飾外), 那么你就必須重寫dealloc的方法, 例:



如圖所示, 我定義了一個(gè)NSString的屬性, 所以對(duì)應(yīng)的重寫了dealloc這個(gè)方法.

本次對(duì)于內(nèi)存管理的梳理知識(shí)到這里結(jié)束, 這些只是基礎(chǔ)知識(shí), 日后我還會(huì)不斷的完善, 希望大俠們能夠指出不足, 互相學(xué)習(xí), 互相進(jìn)步, 謝謝各位.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末碟绑,一起剝皮案震驚了整個(gè)濱河市俺猿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌格仲,老刑警劉巖押袍,帶你破解...
    沈念sama閱讀 211,376評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異凯肋,居然都是意外死亡谊惭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門侮东,熙熙樓的掌柜王于貴愁眉苦臉地迎上來圈盔,“玉大人,你說我怎么就攤上這事悄雅∏茫” “怎么了?”我有些...
    開封第一講書人閱讀 156,966評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵宽闲,是天一觀的道長众眨。 經(jīng)常有香客問我握牧,道長,這世上最難降的妖魔是什么娩梨? 我笑而不...
    開封第一講書人閱讀 56,432評(píng)論 1 283
  • 正文 為了忘掉前任沿腰,我火速辦了婚禮,結(jié)果婚禮上狈定,老公的妹妹穿的比我還像新娘颂龙。我一直安慰自己,他們只是感情好掸冤,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評(píng)論 6 385
  • 文/花漫 我一把揭開白布厘托。 她就那樣靜靜地躺著,像睡著了一般稿湿。 火紅的嫁衣襯著肌膚如雪铅匹。 梳的紋絲不亂的頭發(fā)上饺藤,一...
    開封第一講書人閱讀 49,792評(píng)論 1 290
  • 那天包斑,我揣著相機(jī)與錄音,去河邊找鬼涕俗。 笑死罗丰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的再姑。 我是一名探鬼主播萌抵,決...
    沈念sama閱讀 38,933評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼元镀!你這毒婦竟也來了绍填?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,701評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤栖疑,失蹤者是張志新(化名)和其女友劉穎讨永,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體遇革,經(jīng)...
    沈念sama閱讀 44,143評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡卿闹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了萝快。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锻霎。...
    茶點(diǎn)故事閱讀 38,626評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖揪漩,靈堂內(nèi)的尸體忽然破棺而出旋恼,到底是詐尸還是另有隱情,我是刑警寧澤氢拥,帶...
    沈念sama閱讀 34,292評(píng)論 4 329
  • 正文 年R本政府宣布蚌铜,位于F島的核電站,受9級(jí)特大地震影響嫩海,放射性物質(zhì)發(fā)生泄漏冬殃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評(píng)論 3 313
  • 文/蒙蒙 一叁怪、第九天 我趴在偏房一處隱蔽的房頂上張望审葬。 院中可真熱鬧,春花似錦奕谭、人聲如沸涣觉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽官册。三九已至,卻和暖如春难捌,著一層夾襖步出監(jiān)牢的瞬間膝宁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國打工根吁, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留员淫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓击敌,卻偏偏與公主長得像介返,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子沃斤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評(píng)論 2 348

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