MRC&ARC之理解總結

MRC:

1.為什么要進行內存管理?

iphone手機的內存是有限的,目前最大內存是2G,當運行頻繁多的app的時候,會占用大量的內存,當我們的app占用的內存大于40M的時候,ios系統會發出警告,當超過45M的時候系統會發出第二次警告,當占用內存超過120M的時候,app會閃退,所以我們需要對內存空間進行一個合理的管理,用以保證我們的app能夠流暢的運行;

2.什么是內存管理?

當我們編寫程序的時候,會聲明各種各樣的變量編寫各種各樣的代碼,他們都會占用內存,但是并不是所有的代碼和內存都是有我們進行釋放;
內存分為5個區域:棧、堆、bss段、數據段、代碼段;
棧:存放的是局部變量,當局部變量的作用域結束的時候就會由系統進行釋放局部變量所占用的內存空間;
堆:存放的是程序員手動申請的變量,手動申請的變量可以由程序員手動編寫代碼進行釋放;
bass段:存放的是為初始化的全局變量和靜態變量,當全局變量和靜態變量進行初始化的時候系統就會回收他們所占用的空間,然后把他們存放到數據段;
數據段:存放的是已經初始化了的全局變量和靜態變量和常量,當程序結束的時候由系統進行回收釋放;
代碼段:存放的是我們編寫的代碼,當程序結束的時候由系統進行回收釋放;
所以我們管理的其實只有堆空間。

3.如何進行內存管理?

在MRC機制下,每一個對象都有一個四個字節的存儲空間(一個整數),記錄對象被引用的數量,一個對象被創建出來以后,默認的引用計數為1,當一個對象引用計數為零的時候,對象會被立即回收,所以我們可以通過對引用計數的操作來進行對象的回收,并完成內存空間的操作;

4.引用計數是如何進行操作的?

我們可以向對象發送一些消息來操作對象的引用計數,發送retain消息可以添加一個引用計數,發送release消息可以減少一個引用計數,當一個對象的應用計數為零的時候他會被立即回收;

5.內存管理的原則:

A.當對象被創建出來以后,對象的引用計數默認是1,所以在這個對象使用完畢以后,我們應該為這個對象發送一條release消息,保證這個對象在使用完畢以后應用計數變為零,并且占用的內存空間被回收;
B. 當對象被別人使用的時候,別人就會為這個對象發送retain消息,表示使用的人多了一個,當別人不在使用對象的時候,別人就會為對象發送release消息,表示使用的人少了一個;
C. 當對象還有人正在使用的時候,對象就不應該被回收;
D.誰發送了retain消息,當使用完畢之后,誰要發送release消息;

ARC:

ARC是iOS 5推出的新功能,全稱叫 ARC(Automatic Reference Counting)。簡單地說,就是代碼中自動加入了retain/release,原先需要手動添加的用來處理內存管理的引用計數的代碼可以自動地由編譯器完成了。
簡單地理解ARC,就是通過指定的語法,讓編譯器(LLVM 3.0)在編譯代碼時,自動生成實例的引用計數管理部分代碼。有一點,ARC并不是GC,它只是一種代碼靜態分析(Static Analyzer)工具。

ARC主要提供了4種修飾符,他們分別是:__strong,__weak,__autoreleasing,__unsafe_unretained
__strong

表示引用為強引用。對應在定義property時的"strong"。所有對象只有當沒有任何一個強引用指向時,才會被釋放。
注意:如果在聲明引用時不加修飾符,那么引用將默認是強引用。當需要釋放強引用指向的對象時,需要將強引用置nil。

__weak

表示引用為弱引用。對應在定義property時用的"weak"。弱引用不會影響對象的釋放,即只要對象沒有任何強引用指向,即使有100個弱引用對象指向也沒用,該對象依然會被釋放。不過好在,對象在被釋放的同時,指向它的弱引用會自動被置nil,這個技術叫zeroing weak pointer。這樣有效得防止無效指針、野指針的產生。__weak一般用在delegate關系中防止循環引用或者用來修飾指向由Interface Builder編輯與生成的UI控件

__autoreleasing

表示在autorelease pool中自動釋放對象的引用,和MRC時代autorelease的用法相同。定義property時不能使用這個修飾符,任何一個對象的property都不應該是autorelease型的。
一個常見的誤解是,在ARC中沒有autorelease,因為這樣一個“自動釋放”看起來好像有點多余。這個誤解可能源自于將ARC的“自動”和autorelease“自動”的混淆。其實你只要看一下每個iOS App的main.m文件就能知道,autorelease不僅好好的存在著,并且變得更fashion了:不需要再手工被創建,也不需要再顯式得調用[drain]方法釋放內存池。


以下兩行代碼的意義是相同的。

NSString *str = [[[NSString alloc] initWithFormat:@"hehe"] autorelease]; // MRC
NSString *__autoreleasing str = [[NSString alloc] initWithFormat:@"hehe"]; // ARC

__autoreleasing在ARC中主要用在參數傳遞返回值(out-parameters)和引用傳遞參數(pass-by-reference)的情況下。
比如常用的NSError的使用:

NSError *__autoreleasing error; 
if (![data writeToFile:filename options:NSDataWritingAtomic error:&error]) 
{ 
  NSLog(@"Error: %@", error); 
}

注意,如果你的error定義為了strong型,那么,編譯器會幫你隱式地做如下事情,保證最終傳入函數的參數依然是個__autoreleasing類型的引用。

NSError *error; NSError *__autoreleasing tempError = error; // 編譯器NSError *error; 
NSError *__autoreleasing tempError = error; // 編譯器添加 
if (![data writeToFile:filename options:NSDataWritingAtomic error:&tempError]) 
{ 
  error = tempError; // 編譯器添加 
  NSLog(@"Error: %@", error); 
}

所以為了提高效率,避免這種情況,我們一般在定義error的時候將其(老老實實地=。=)聲明為__autoreleasing類型的:

NSError *__autoreleasing error;
在這里,加上__autoreleasing之后,相當于在MRC中對返回值error做了如下事情:

*error = [[[NSError alloc] init] autorelease];
error指向的對象在創建出來后,被放入到了autoreleasing pool中,等待使用結束后的自動釋放,函數外error的使用者并不需要關心error指向對象的釋放。

另外一點,在ARC中,所有這種指針的指針 (NSError **)的函數參數如果不加修飾符,編譯器會默認將他們認定為__autoreleasing類型。
比如下面的兩段代碼是等同的:

- (NSString *)doSomething:(NSNumber **)value
{
        // do something  
}
- (NSString *)doSomething:(NSNumber * __autoreleasing *)value
{
        // do something  
}

除非你顯式得給value聲明了__strong,否則value默認就是__autoreleasing的。
http://www.cnblogs.com/flyFreeZn/p/4264220.html 這篇文章比較詳細要多看

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,001評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,786評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,986評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,204評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,964評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,354評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,410評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,554評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,106評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,918評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,093評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,648評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,342評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,755評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,009評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,839評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,107評論 2 375

推薦閱讀更多精彩內容

  • 內存管理 簡述OC中內存管理機制。與retain配對使用的方法是dealloc還是release,為什么?需要與a...
    丶逐漸閱讀 1,986評論 1 16
  • 29.理解引用計數 Objective-C語言使用引用計數來管理內存,也就是說,每個對象都有個可以遞增或遞減的計數...
    Code_Ninja閱讀 1,518評論 1 3
  • 概述 在iOS中開發中,我們或多或少都聽說過內存管理。iOS的內存管理一般指的是OC對象的內存管理,因為OC對象分...
    DamonMok閱讀 4,030評論 2 20
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結起來就是把...
    Dove_iOS閱讀 27,197評論 30 471
  • 6、ARC仍然遵循MRC的內存管理方式,4個基本規則在ARC下仍然是有效的,區別只在于:MRC模式下需要手動鍵入r...
    楊淳引閱讀 621評論 0 0