@autorelease{} 的詳細介紹

前言:當您向一個對象發送一個autorelease消息時,Cocoa就會將該對象的一個引用放入到最新的自動釋放池。它仍然是個正當的對象,因此自動釋放池 定義的作用域內的其它對象可以向它發送消息。當程序執行到作用域結束的位置時,自動釋放池就會被釋放,池中的所有對象也就被釋放。

1.? ojc-c 是通過一種"referring counting"(引用計數)的方式來管理內存的,? 對象在開始分配內存(alloc)的時候引用計數為一,以后每當碰到有alloc,new,copy,retain的時候引用計數都會加一,? 每當碰到release和autorelease的時候引用計數就會減一,如果此對象的計數變為了0, 就會被系統銷毀.

2. NSAutoreleasePool 就是用來做引用計數的管理工作的,這個部分后面會詳細說到.

3. autorelease和release沒什么區別,只是引用計數減一的時機不同而已,autorelease會在對象的使用真正結束的時候才做引用計數減一.

4.設定項目編譯環境為ARC下時,編譯器會幫助我們在程序的入口main函數就調用NSAutoreleasePool


,這樣保證程序中不調用NSAutoreleasePool,但在退出時自動釋放

1.NSAutoreleasePool是什么?

NSAutoreleasePool實際上是個對象引用計數自動處理器,在官方文檔中被稱為是一個類。

NSAutoreleasePool可以同時有多個,它的組織是個棧,總是存在一 個棧頂pool,也就是當前pool,每創建一個pool,就往棧里壓一個,改變當前pool為新建的pool,然后,每次給pool發送drain消 息,就彈出棧頂的pool,改當前pool為棧里的下一個 pool。

2.NSAutoreleasePool可以用來做什么,怎么用?

NSAutoreleasePool可以在一定程度上幫助我們蘋果開發程序員管理內存,讓我們的工作更加嚴密,簡便。

1)在ARC項目中,系統會自動幫助我們在程序中嵌入NSAutoreleasePool,此為蘋果公司程序員在寫這個編譯器的時候設定的;

2)在MRC項目中,我們需要自己去創建NSAutoreleasePool類對象去幫助我們管理內存;

3)使用應注意:

a.在ARC項目中我們同樣可以創建NSAutoreleasePool類對象去幫助我們更精確的管理內存問題。

b. NSAutoreleasePool的管理范圍是在NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];與[pool release];之間的對象

c..既然ARC項目中設置了ARC,為什么還要使用@autoreleasepool?(注意a的案例解釋)

ARC 并不是舍棄了@autoreleasepool,而是在編譯階段幫你插入必要的retain/release/autorelease的代碼調用。

所以,跟你想象的不一樣,ARC 之下依然是延時釋放的,依然是依賴于NSAutoreleasePool,跟非 ARC 模式下手動調用那些函數本質上毫無差別,只是編譯          器來做會保證引用計數的正確性。

參考:Retain count semantics in ARC

What's @autoreleasepool

d.NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];

當執行[pool autorelease]的時候,系統會進行一次內存釋放,把autorelease的對象釋放掉,如果沒有NSAutoreleasePool , 那這些內存不會釋放

注意,對象并不是自動被加入到當前pool中,而是需要對對象發送autorelease消息,這樣,對象就被加到當前pool的管理里了。當當前pool接受到drain消息時,它就簡單的對它所管理的所有對象發送release消息。(如例子1)

e.在ARC項目中.不能直接使用autorelease pools,而是使用@autoreleasepool{},

@autoreleasepool{}比直接使用NSAutoreleasePool效率高。不使用ARC的時候也可以使用(autorelease嵌套)

4)使用例子:

例子1:

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

NSString* nsstring;

char* cstring = "Hello CString";

nsstring = [NSString stringWithUTF8String:cstring];

[pool release];(這一行代碼就是在給pool發送drain消息了)

官方API摘抄翻譯:

3.autorelease的原理是什么?

Autorelease實際上只是把對release的調用延遲了,對于每一個Autorelease,系統只是把該Object放入了當 前的Autorelease pool中,當該pool被釋放時,該pool中的所有Object會被調用Release。

4.!!!autorelease何時釋放?

對于autorelease pool本身,會在如下兩個條件發生時候被釋放(詳細信息請參見第5條)

1)、手動釋放Autorelease pool

2)、Runloop結束后自動釋放

對于autorelease pool內部的對象在引用計數的retain == 0的時候釋放。release和autorelease pool 的 drain都會觸發retain--事件。

5、autorelease釋放的具體原理是什么?

要搞懂具體原理,則要先要搞清楚autorelease何時會創建。

我們的程序在main()調用的時候會自動調用一個autorelease,然后在每一個 Runloop, 系統會隱式創建一個Autorelease pool,這樣所有的release? pool會構成一個象CallStack一樣的一個棧式結構,在每一個Runloop結束時,當前棧頂的 Autorelease? pool(main()里的autorelease)會被銷毀,這樣這個pool里的每個Object會被release。

可以把autorelease? pool理解成一個類似父類與子類的關系,main()創建了父類,每個Runloop自動生成的或者開發者自定義的autorelease? pool都會成為該父類的子類。當父類被釋放的時候,沒有被釋放的子類也會被釋放,這樣所有子類中的對象也會收到release消息。

那什么是一個Runloop呢? 一個UI事件,Timer call, delegate call, 一個鼠標事件,鍵盤按下(MAC OSX),或者iphone上的觸摸事件,異步http連接下后當接收完數據時,都會是一個新的Runloop。

一般來說,消息循環運行一次是毫秒級甚至微秒級的,因此autorelease的效率仍然是非常高的,確實是一個巧妙的設計。

6、使用有什么要注意的?

1)、NSAutoreleasePool可以創建一個autorelease pool,但該對象本身也需要被釋放,如:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init;

// Code benefitting from a local autorelease pool.

[pool release];

復制代碼

在引用計數環境下,使用[pool release]或[pool drain]效果是相同的,drain僅適用于max os高版本,低版本不適用,而release通用,其它并無太大差別。

2)、在ARC下,不能使用上述方式調用autorelease,而應當使用@autoreleasepool,如:

@autoreleasepool {

// Code benefitting from a local autorelease pool.

}

復制代碼

3)、盡量避免對大內存使用該方法,如圖片。對于這種延遲釋放機制,還是盡量少用,最好只用在方法內返回小塊內存申請地址值的情況下,且參考和領會OC的一些系統方法,如:[NSString stringWithFormat:]。

4)、不要把大量循環操作放到同一個NSAutoreleasePool之間,這樣會造成內存峰值的上升。

7、關于多線程,有什么要注意的?

我還未實際使用到,在官方API翻譯出類似如下語句:

1)、對于不同線程,應當創建自己的autorelease pool。如果應用長期存在,應該定期drain和創建新的autorelease pool

下面這句話摘自官方API,大概是說多線程中如果沒有使用到cocoa的相關調用,則不需要創建autorelease pool,我一直沒有理解透徹

If, however, your detached thread does not make Cocoa calls, you do not need to create an autorelease pool.

2)、如果不是使用的NSThread,就不要用aoturelease pool,除非你是多線程模式(multithreading mode) ,可以使用NSThread的isMultiThreaded方法測試你的應用是否是多線程模式

PS:

我把它理解為:新開線程最好實現NSAutoreleasePool(當 我們點擊一個App中的一個按鈕或者其他可以觸碰開啟新業務的UI控件,在程序里面就會自動開啟一條新線程,當我們不用這個業務的時候,就需要程序幫我們 提前在“程序的主窗口的所有代碼編譯結束后”之前關閉這條線程以優化線程的使用,一定程度上盡量避免線程開啟太多占用CPU嚴重引起的卡頓問題)(業務邏 輯處理-業務線程優化)

詳細可以參考官方API的NSAutoreleasePool Class Reference

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

推薦閱讀更多精彩內容

  • 前言:當您向一個對象發送一個autorelease消息時,Cocoa就會將該對象的一個引用放入到最新的自動釋放池。...
    mengyingguo閱讀 1,141評論 0 0
  • 37.cocoa內存管理規則 1)當你使用new,alloc或copy方法創建一個對象時,該對象的保留計數器值為1...
    如風家的秘密閱讀 880評論 0 4
  • 前言 從我開始學習iOS的時候,身邊的朋友、網上的博客都告訴我iOS的內存管理是依靠引用計數的,然后說引用計數大于...
    蓋世英雄_ix4n04閱讀 570評論 0 1
  • 內存管理 簡述OC中內存管理機制。與retain配對使用的方法是dealloc還是release,為什么?需要與a...
    丶逐漸閱讀 1,986評論 1 16
  • 這學期意外的很喜歡上課的日子 許是能趁著這時候可以明目張膽的做些悠閑的事情 所謂悠閑 也無外乎刷手機和胡思亂想了 ...
    好一朵迎春fa閱讀 312評論 0 0