您好,登錄后才能下訂單哦!
Advanced Autorelease Pool 高級自動釋放池
在之前的章節(jié)你已經(jīng)學(xué)習(xí)了很多基本的內(nèi)存方面的知識。這個部分將會涉及到使用自動釋放的高級技術(shù),同時展示你應(yīng)該在哪里使用,從而在受限的情況下獲得比較高的性能。
在每一個線程中,你應(yīng)該要有一個自動釋放池來收集和存儲所有自動釋放的對象。如果在每一個線程中,沒有自動釋放池的話,所有的autoreleased對象會泄露,你將會有一個重大的內(nèi)存泄露。自動釋放池是通過棧的形式組織在一起的;下面部分會解釋。
自動釋放池和棧
自動釋放池存儲在一個棧中,通常被理解成嵌套的。無論何時你創(chuàng)建一個新的自動釋放池,它都會被push到棧的頂部。然后所有新的autoreleased對象會被push到這個新的自動釋放池中。
通過下面的代碼你可以看到,對象(比如myArray和myString)內(nèi)部的方法doSomething將會存儲在myPool中,而不是應(yīng)用的main pool中:
- (void)doSomething {
@autoreleasepool {
NSArray *myArray = [NSArray array];
NSString *myString = [NSString string];
}
}
這是main方法的main pool:
int main(int argc, char *argv[]){
@autoreleasepool {
int retVal = UIApplicationMain(argc, argv, nil, nil);
}
return retVal;
}
在@autoreleasepool塊結(jié)束的時候,當(dāng)時間生命周期結(jié)束時,所有存儲在這個pool中的autoreleased對象jiang將被released。
圖7-9展示了這個概念。對于一個好的性能來說,這是一個非常重要的概念 -- 知道盡可能快的release對象。
自動釋放池和線程
當(dāng)創(chuàng)建一個新的線程時,你需要創(chuàng)建一個新的自動釋放池對象,然后將這個pool和新的線程聯(lián)系在一起。因此當(dāng)線程停止時,你的自動釋放池會deallocated,所有的autoreleased對象也會deallocated。第6章我會深入的討論這個主題,所以你應(yīng)該復(fù)習(xí)一下,如果你在理解概念時需要一些幫助的話。
自動釋放池對性能的影響
舊的內(nèi)存管理規(guī)則依然能夠應(yīng)用在用ARC編寫的代碼上,如果你沒有使用new,alloc和copy調(diào)用一個方法,這個對象就已經(jīng)是autoreleased了。如果你在一個循環(huán)中創(chuàng)建了很多的autoreleased對象,很快內(nèi)存就會耗盡。
這個代碼演示了在循環(huán)中處理內(nèi)存管理最好的方法:
- (void)doSomethingWithAutoRelease {
for (int i = 0; i < 1000; i++) {
@autoreleasepool {
Product *product = [Product productWithItemID:@""];
// process and display the product here
}
}
}
在循環(huán)結(jié)束的時候,以及在@autoreleasepool塊的尾部,所有的autoreleased對象會released。這種方法你能夠控制和release所有位使用的對象和回收你的內(nèi)存。
Instruments
當(dāng)我討論使用設(shè)備和模擬器測試的時候,第2章已經(jīng)介紹過Instruments。在這個部分,我將簡短的討論一些更加更高級的問題,這些問題會影響到你應(yīng)該選擇什么樣的內(nèi)存管理方式。
大部分時間,你需要使用到4中主要的instruments。
Static Analyzer
Leaks Instruments
Zombie
Object allocation
Static Analyzer
static Analyzer是一個比較快速的方法檢查一些微小的比較明顯的內(nèi)存泄露。例如,如果你alloc了一個新的對象,沒有在方法內(nèi)release它,如圖7-10所示,Static Analyzer能夠快速的發(fā)現(xiàn)。
Leak Instrument
Leaks Instrument更加復(fù)雜,它需要時間允許和分析,但是會給出更好的結(jié)果。在運(yùn)行過程中,它能夠檢測到所有數(shù)據(jù)軌跡的內(nèi)存泄露。
Leaks Instrument能給出內(nèi)存泄露對象更多的細(xì)節(jié)信息,如圖7-11.
同樣能夠顯示泄露確切的發(fā)生在哪一行(圖 7-12)。
Zombie
Zombie能夠幫助你檢查EXEC_BAD_ACCESS導(dǎo)致的應(yīng)用程序崩潰的問題。這是非常有幫助的,如果你的應(yīng)用老是崩潰,但是通過日志或檢查代碼又發(fā)現(xiàn)不了問題的話。
如圖7-13,Zombie會顯示給你一個actions的list,包括malloc,autorelease,retain,和release,當(dāng)應(yīng)用崩潰的時候。你使用Zombie跟蹤autorelease和release方法。
Object Allocation
Object allocation是我要介紹的內(nèi)存相關(guān)的最后一個工具。它顯示了運(yùn)行過程中,所有內(nèi)存的使用情況。這個工具是非常有用的,當(dāng)內(nèi)存使用增長很多,你需要跟蹤使用內(nèi)存較多的那些代碼。
圖7-14顯示了代碼所在行,對象創(chuàng)建的時間,和創(chuàng)建對象的調(diào)用者。
Memory Waring Levels
最后我要討論的是關(guān)于內(nèi)存警告。當(dāng)你的內(nèi)存增長到一定點時,iOS系統(tǒng)會嘗試告訴你,通過在view controller中調(diào)用didReceiveWarning方法。你應(yīng)該在這個方法中釋放一些內(nèi)存。
注意:在你的應(yīng)用中還有其他方法收到內(nèi)存警告:applocation delegate收到內(nèi)存警告,然后在其他對象中調(diào)用相應(yīng)的方法,或者你的對象通過NSNotification注冊了接受內(nèi)存警告的通知。 |
內(nèi)存警告的第1級別是最重要的:它意味著你的代碼已經(jīng)快速的使用了很多內(nèi)存。否則,你的app將會收到第2個級別的警告,然后會崩潰。
總結(jié)
內(nèi)存對你的app的性能有重要影響。如果你不恰當(dāng)?shù)氖褂脮?dǎo)致你的app崩潰。在本章,你學(xué)到了在objective-c中很多關(guān)于內(nèi)存管理方面的重要概念,這能夠幫助你避免內(nèi)存泄露和應(yīng)用程序崩潰。UIViewController的生命周期同樣非常重要,因為它和內(nèi)存的管理和控制有關(guān)。它同樣會影響到應(yīng)用的性能和體驗。最后,你學(xué)到了當(dāng)在處理內(nèi)存時,autorelease和release的不同,以及何時應(yīng)該用其中的一個替代另外一個。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。