iOS 5與iOS 6的low-memory 處理簡介

來源:互聯網
上載者:User

行動裝置終端的記憶體極為有限,應用程式必須做好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;    }

查看本欄目更多精彩內容:http://www.bianceng.cnhttp://www.bianceng.cn/OS/extra/

不要忘記一點,每當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 ,此時資料全部重新建立,簡單相容無壓力~~

UPDATE -  2013.5.21

1.評論中,一位仁兄提供了他的解決辦法:

在 didReceiveMemoryWarning 方法中判斷,如果當前version >= 6.f ,就使用performSelectorOnMainThread 調用 viewDidUnload ,可以複用為了相容5寫的 viewDidUnload 方法。

想法很好,但是我認為其實大可不必,因為在iOS6中,之前viewDidUnload實現的事情已經完全託管了,並不是沒有做相關處理,不需要在手動調用viewDidUnload。

2.也有人不推薦使用本文提到的清self.view的這種懶人相容方法,具體可看:再見,viewDidUnload方法

我認為,這的確是值得每個人思考的,也歡迎大家說說自己的想法。

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.

作者:csdn 念茜

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.