iOS 5與iOS 6的 low-memory 處理

來源:互聯網
上載者:User

iOS 5 與 iOS 6 的 low-memory 處理

 

 

行動裝置終端的記憶體極為有限,應用程式必須做好low-memory處理工作,才能避免程式因記憶體使用量過大而崩潰。

low-memory 處理思路

通常一個應用程式會包含多個view controllers,當從view跳轉到另一個view時,之前的view只是不可見狀態,並不會立即被清理掉,而是儲存在記憶體中,以便下一次的快速顯現。但是如果應用程式接收到系統發出的low-memory warning,我們就不得不把當前不可見狀態下的views清理掉,騰出更多的可使用記憶體;當前可見的view controller也要合理釋放掉一些快取資料,圖片資源和一些不是正在使用的資源,以避免應用程式崩潰。

思路是這樣,具體的實施根據系統版本不同而略有差異,本文將詳細說明一下iOS 5與iOS 6的low-memory處理。

 

 

iOS 5 的處理

在iOS 6 之前,如果應用程式接收到了low-memory警告,當前不可見的view controllers會接收到viewDidUnload訊息(也可以理解為自動調用viewDidUnload方法),所以我們需要在 viewDidUnload 方法中釋放掉所有 outlets ,以及可再次建立的資源。當前可見的view controller 通過didReceiveMemoryWarning 合理釋放資源,具體見代碼注釋。

舉一個簡單的例子,有這樣一個view controller:

 

 

@interface MyViewController : UIViewController {    NSArray *dataArray;}@property (nonatomic, strong) IBOutlet UITableView *tableView;@end

 

 

對應的處理則為:

#pragma mark -#pragma mark Memory management- (void)didReceiveMemoryWarning {    // Releases the view if it doesn't have a superview.    [super didReceiveMemoryWarning];        // Relinquish ownership any cached data, images, etc that aren't in use.}- (void)viewDidUnload {    // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.    // For example: self.myOutlet = nil;    self.tableView = nil;    dataArray = nil;        [super viewDidUnload];}

iOS 6 的處理

iOS 6 廢棄了viewDidUnload方法,這就意味著一切需要我們自己在didReceiveMemoryWarning中操作。

具體應該怎麼做呢?

 

 

1.將 outlets 置為 weak

當view dealloc時,沒有人握著任何一個指向subviews的強引用,那麼subviews執行個體變數將會自動置空。

@property (nonatomic, weak) IBOutlet UITableView *tableView;

2.在didReceiveMemoryWarning中將快取資料置空

#pragma mark -#pragma mark Memory management- (void)didReceiveMemoryWarning{    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.    dataArray = nil;}

不要忘記一點,每當tableview reload 的時候,需要判斷一下 dataArray ,若為空白則重新建立。

相容iOS 5 與 iOS 6

好吧,重點來了,倘若希望程式相容iOS 5 與 iOS 6怎麼辦呢? 

這裡有一個小技巧,我們需要對didReceiveMemoryWarning 做一些手腳:

#pragma mark -#pragma mark Memory management- (void)didReceiveMemoryWarning{    [super didReceiveMemoryWarning];        if ([self isViewLoaded] && self.view.window == nil) {        self.view = nil;    }        dataArray = nil;}

判斷一下view是否是window的一部分,如果不是,那麼可以放心的將self.view 置為空白,以換取更多可用記憶體。

這樣會是什麼現象呢?假如,從view controller A 跳轉到 view controller B ,然後類比low-memory警告,此時,view controller A 將會執行self.view = nil ; 當我們從 B 退回 A 時, A 會重新調用一次 viewDidLoad ,此時資料全部重新建立,簡單相容無壓力~~

Note:

如果你好奇Apple為什麼廢棄viewDidUnload,可以看看Apple 的解釋:

Apple deprecated viewDidUnload for a good reason. The memory savings from setting a few outlets to nil just weren’t worth it and added a lot of complexity for little benefit. For iOS 6+ apps, you can simply forget about view unloading and only implement didReceiveMemoryWarning if the view controller can let go of cached data that you can recreate on demand later.



 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.