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