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