https://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/ViewLoadingandUnloading/ViewLoadingandUnloading.html
模擬內存警告:
有三種方法可以實現內存警告。
1.模擬器菜單:Hardware-》Simulate Memory Warning
2.用程序的方法實現,只需要一句代碼:
CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), (CFStringRef)@"UISimulatedMemoryWarningNotification", NULL, NULL, true);
3.這是私有api方法:
SEL memoryWarningSel = @selector(_performMemoryWarning);
if ([[UIApplication sharedApplication] respondsToSelector:memoryWarningSel]) {
[[UIApplication sharedApplication] performSelector:memoryWarningSel];
}else {
NSLog(@"%@",@"Whoops UIApplication no loger responds to -_performMemoryWarning");
}
內存警告的處理:
自從iPhone4 支持多任務後,我們需要更加仔細處理內存不足的情形。如果用戶運行我們程序的時候,後臺還跑着N個軟件,那前臺運行的iphone 程序就很容易收到內存不足的警告。
通常情況下,iOS在內存不足時會給用戶一次處理內存資源的機會。當我們的程序在第一次收到內存不足警告時,應該釋放一些不用的資源,以節省部分內存。否則,當內存不足情形依然存在,iOS再次向我們程序發出內存不足的警告時,我們的程序將會被iOS kill掉。
iOS的UIViewController 類給我們提供了處理內存不足的接口。在iOS 3.0 之前,當系統的內存不足時,UIViewController的didReceiveMemoryWarining 方法會被調用,我們可以在didReceiveMemoryWarining 方法裏釋放掉部分暫時不用的資源。
從iOS3.0 開始,UIViewController增加了viewDidUnload方法。該方法和viewDIdLoad相配對。當系統內存不足時,首先UIViewController的didReceiveMemoryWarining 方法會被調用,而didReceiveMemoryWarining 會判斷當前ViewController的view是否顯示在window上,如果沒有顯示在window上,則didReceiveMemoryWarining 會自動將viewcontroller 的view以及其所有子view全部銷燬,然後調用viewcontroller的viewdidunload方法。如果當前UIViewController的view顯示在window上,則不銷燬該viewcontroller的view,當然,viewDidunload也不會被調用了。
但是到了ios6.0之後,這裏又有所變化,ios6.0內存警告的viewDidUnload 被屏蔽,即又回到了ios3.0的時期的內存管理方式。
iOS3-iOS6.0以前版本收到內存警告:
調用didReceiveMemoryWarning內調用super的didReceiveMemoryWarning會將controller的view進行釋放。所以我們不能將controller的view再次釋放。
處理方法:
-(void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];//如沒有顯示在window上,會自動將self.view釋放。
// ios6.0以前,不用在此做處理,self.view釋放之後,會調用下面的viewDidUnload函數,在viewDidUnload函數中做處理就可以了。
}
-(void)viewDidUnload
{
// Release any retained subviews of the main view.不包含self.view
[super viewDidUnload];
//處理一些內存和資源問題。
}
iOS6.0及以上版本的內存警告:
調用didReceiveMemoryWarning內調用super的didReceiveMemoryWarning調只是釋放controller的resouse,不會釋放view
處理方法:
-(void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];//即使沒有顯示在window上,也不會自動的將self.view釋放。
// Add code to clean up any of your own resources that are no longer necessary.
// 此處做兼容處理需要加上ios6.0的宏開關,保證是在6.0下使用的,6.0以前屏蔽以下代碼,否則會在下面使用self.view時自動加載viewDidLoad
if ([self.view window] == nil)// 是否是正在使用的視圖
{
// Add code to preserve data stored in the views that might be
// needed later.
// Add code to clean up other strong references to the view in
// the view hierarchy.
self.view = nil;// 目的是再次進入時能夠重新加載調用viewDidLoad函數。
}
}