iPhone內存管理面面觀 自動釋放與便捷方法
我們在前面介紹過iPhone軟件的內存管理如何有效控制“對象所有權與引用計數”,在這篇文章中我們將介紹“自動釋放”(Auto release)與“便捷方法”(convenience method)。
51CTO推薦專題:iPhone應用程序開發初探
有時候一個所有者創建一個對象后,會立刻將該對象的指針傳遞給其它所有者。這時,這個創建者不希望再擁有這個對象,但如果立刻給它發送一個release消息會導致這個對象被立刻釋放掉——這樣其它所有者還沒有來得及保留該對象。解決這個兩難問題的方法是,給對象發送一個autorelease消息:這樣創建者不再擁有該對象的所有權;該對象成為自動釋放的對象,但是不會立刻被釋放掉;其它所有者可以有時間保留或復制該對象,并成為其唯一所有者。
我們來看一個自動釋放的例子(代碼清單3-1)。一個所有者先用alloc方法創建一個對象;此時該所有者擁有這個對象,對象的引用計數為1。緊接著,所有者自動釋放該對象;所有者此時已經放棄了所有權,但對象的引用計數在一段時間內依然為1。我們可以看出自動釋放的另一個好處:你不會因為在后面忘記給對象發送release消息而造成內存泄露。
代碼清單3-1
- -(Object*)returnAutoreleaseObject {
- Object* obj = [[Object alloc] init];
- return [obj autorelease];
- }
與自動釋放相關的,有一大類構造方法(constructor method),由它們構造的對象直接就是自動釋放的對象;這一類構造方法叫做便捷方法。比如下面這句的字符串就是一個自動釋放的對象,stringWithFormat:就是一個便捷方法。
- NSString* string = [NSString stringWithFormat:@”autoreleaseString”];
再舉幾個便捷方法的例子,方便讀者以后的開發。
1.NSArray的arrayWithObjects:和arrayWithArray:。
2.UIImage的imageNamed:。
3.NSNumber的numberWithBool等。
現在我們已經解釋了,autorelease方法會在一段時間以后釋放掉一個對象,在這段時間內我們可以安全地使用該對象。那么這段時間究竟是多久呢?我們需要先更多地了解自動釋放的機制,再來回答這個問題。
讓我們先來看看自動釋放池。自動釋放池是NSAutoreleasePool的實例,其中包含了收到autorelease消息的對象。當一個自動釋放池自身被銷毀(dealloc)時,它會給池中每一個對象發送一個release消息(如果你給一個對象多次發送autorelease消息,那么當自動釋放池銷毀時,這個對象也會收到同樣數目的release消息)。可以看出,一個自動釋放的對象,它至少能夠存活到自動釋放池銷毀的時候。
那么自動釋放池何時被創建,又何時被銷毀呢?在每一個事件周期(event cycle)的開始,系統會自動創建一個自動釋放池;在每一個事件周期的結尾,系統會自動銷毀這個自動釋放池。一般情況下,你可以理解為:當你的代碼在持續運行時,自動釋放池是不會被銷毀的,這段時間內你也可以安全地使用自動釋放的對象;當你的代碼運行告一段落,開始等待用戶輸入(或者其它事件)時,自動釋放池就會被釋放掉,池中的對象都會收到一個release消息,有的可能會因此被銷毀。
到此為止,相信你已經對自動釋放的機制有了一個大體的了解。自動釋放而非直接釋放,可以幫助你節省一些代碼量,提高開發速度。但是它有一個直接的缺點:它延緩了對象的釋放,在有大量自動釋放的對象時,會占用大量內存資源。因此,你需要避免將大量對象自動釋放。并且,在以下兩種情況下,你需要手動建立并手動銷毀掉自動釋放池:
1.當你在主線程外開啟其它線程時:系統只會在主線程中自動生成并銷毀掉自動釋放池。
2.當你在短時間內制造了大量自動釋放對象時:及時地銷毀有助于有效利用iPad上有限地內存資源。
【編輯推薦】





















