亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

ios6處理內存警告

2019-11-14 20:14:00
字體:
來源:轉載
供稿:網友

   iphone下每個app可用的內存是被限制的,如果一個app使用的內存超過20M,則系統會向該app發送Memory Warning消息。收到此消息后,app必須正確處理,否則可能出錯或者出現內存泄露。

     app收到Memory Warning后會調用:UIapplication::didReceiveMemoryWarning -> UIApplicationDelegate::applicationDidReceiveMemoryWarning,然后調用當前所有的viewController進行處理。因此處理的主要工作是在viewController。

    當我們的程序在第一次收到內存不足警告時,應該釋放一些不用的資源,以節省部分內存。否則,當內存不足情形依然存在,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-iOS5.0以前版本收到內存警告:
調用didReceiveMemoryWarning內調用super的didReceiveMemoryWarning會將controller的view進行釋放。所以我們不能將controller的view再次釋放。
處理方法:
        

java代碼                          

  1. -(void)didReceiveMemoryWarning  
  2.        {  
  3.                 [super didReceiveMemoryWarning];//如沒有顯示在window上,會自動將self.view釋放。  
  4.                 // ios6.0以前,不用在此做處理,self.view釋放之后,會調用下面的viewDidUnload函數,在viewDidUnload函數中做處理就可以了。  
  5.        }  
  6.        -(void)viewDidUnload  
  7.        {  
  8.               // Release any retained subviews of the main view.不包含self.view  
  9.               //處理一些內存和資源問題。  
  10. 10.                [super viewDidUnload];  
  11. 11.                
  12. 12.        }  

 

 

    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時自動加載viewDidUnLoad

            if ([[UIDevice currentDevice].systemVersion floatValue] >= 6.0) {

             //需要注意的是self.isViewLoaded是必不可少的,其他方式訪問視圖會導致它加載 ,在WWDC視頻也忽視這一點。

             if (self.isViewLoaded && !self.view.window)// 是否是正在使用的視圖
             {
                   // 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函數。
             }

           }
    }

 

但是似乎這么寫相對于以前并不省事。最終我們找到一篇文章,文章中說其實并不值得回收這部分的內存,原因如下:

1. UIView是UIResponder的子類,而UIResponder有一個CALayer的成員變量,CALayer是具體用于將自己畫到屏幕上的。

2. CALayer是一個bitmap圖象的包裝類,當UIView調用自身的drawRect時,CALayer才會創建這個bitmap圖象類。

3. 具體占內存的其實是一個bitmap圖象類,CALayer只占48bytes, UIView只占96bytes。而一個iPad的全屏UIView的bitmap類會占到12M的大小!

4.在iOS6時,當系統發出MemoryWarning時,系統會自動回收bitmap類。但是不回收UIView和CALayer類。這樣即回收了大部分內存,又能在需要bitmap類時,根據CALayer類重建。

    所以,iOS6這么做的意思是:我們根本沒有必要為了幾十byte而費力回收內存。

 

--------------------------切糕分割線--------------

PS:

1、關于這個的官方文檔:https://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/ViewLoadingandUnloading/ViewLoadingandUnloading.html

2、zon2012貌似都沒有ios6的這個兼容(其實view是沒問題的,關鍵是資源)

 

分享到:  

xcode4.5(iOS 6)開發與之前的差異 | IOS發送Email的方法

評論

1 樓 嘯笑天 2013-05-14  

移動設備終端的內存極為有限,應用程序必須做好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.


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲国产成人精品久久| 中文字幕国产日韩| 久久久av免费| 国产丝袜精品视频| 欧美精品在线播放| 欧美猛交ⅹxxx乱大交视频| 亚洲精品国产综合区久久久久久久| 国产精品网红福利| 2018中文字幕一区二区三区| 欧美在线观看视频| 91精品国产高清久久久久久| 国内精品久久久| 亚洲欧美www| 国产日本欧美在线观看| 国产午夜精品久久久| 国产成人精品免高潮在线观看| 国产日韩欧美自拍| 亚洲成av人片在线观看香蕉| 欧美孕妇与黑人孕交| 国产成人精品一区二区在线| 亚洲精品网址在线观看| 国产网站欧美日韩免费精品在线观看| 久久夜精品va视频免费观看| 亚洲精品按摩视频| 国产精品www| 6080yy精品一区二区三区| 国产成人精品免费久久久久| 日韩在线精品视频| 亚洲激情视频在线播放| 国产精品福利观看| 日韩精品免费综合视频在线播放| 2019亚洲日韩新视频| 欧美国产一区二区三区| 国产精品久久久久久久久久久久久久| 国产自产女人91一区在线观看| xxxxxxxxx欧美| 91av在线播放视频| 色婷婷亚洲mv天堂mv在影片| 国产精品男女猛烈高潮激情| 亚洲va久久久噜噜噜| 午夜免费久久久久| 精品欧美激情精品一区| 欧美日韩另类字幕中文| 91国内在线视频| 中文字幕国产亚洲2019| 奇米成人av国产一区二区三区| 亚洲精品少妇网址| 在线看片第一页欧美| 欧美亚洲国产日韩2020| 青青在线视频一区二区三区| 国产精品第8页| 久久精品夜夜夜夜夜久久| 午夜免费日韩视频| 亚洲精品国产成人| 国产美女扒开尿口久久久| 国产欧美亚洲精品| 国产精品网红直播| 国产精品9999| 国产精品久久久久久久久久久不卡| 国外日韩电影在线观看| 欧美极品少妇与黑人| 久久的精品视频| zzijzzij亚洲日本成熟少妇| 欧美精品福利在线| 国模吧一区二区三区| 这里只有精品在线播放| 亚洲国产精品久久91精品| 美女av一区二区| 欧美日韩在线观看视频| 91精品在线播放| 日韩av手机在线| 日韩国产精品一区| 日韩av影院在线观看| 欧美高跟鞋交xxxxhd| 欧美国产视频日韩| 日韩在线观看免费全| 欧美日韩亚洲一区二区三区| 全亚洲最色的网站在线观看| 亚洲а∨天堂久久精品9966| 精品久久久中文| 国产婷婷成人久久av免费高清| 日韩黄色在线免费观看| 日韩美女免费线视频| 91青草视频久久| 久久亚洲综合国产精品99麻豆精品福利| 日韩在线播放一区| 日韩电影免费观看中文字幕| 8x拔播拔播x8国产精品| 亚洲人午夜精品免费| 亚洲天堂色网站| 国产精品你懂得| 国产成人亚洲精品| 亚洲自拍偷拍视频| 欧美日韩午夜视频在线观看| 青青精品视频播放| 日韩av免费在线观看| 粗暴蹂躏中文一区二区三区| 欧美电影电视剧在线观看| 欧美精品videosex性欧美| 欧美日韩国产区| 亚洲精品xxxx| 国产日韩欧美91| 国产精品wwwwww| 久久手机免费视频| 久久综合伊人77777尤物| 51久久精品夜色国产麻豆| 亚洲va男人天堂| 亚洲乱码一区二区| 亚洲国产欧美一区二区丝袜黑人| 欧美俄罗斯乱妇| 国产成人在线亚洲欧美| 亚洲黄色有码视频| 亚洲人成网站色ww在线| 美女av一区二区三区| 亚洲国产精品一区二区三区| 国产丝袜精品第一页| 日韩国产一区三区| 91精品在线观| 欧洲美女免费图片一区| 欧美性理论片在线观看片免费| 国产不卡av在线免费观看| 欧美激情a∨在线视频播放| 日韩av免费在线观看| 欧美精品在线网站| www.日韩欧美| 国产成人久久精品| 亚洲国产高清自拍| 国产经典一区二区| 日韩成人高清在线| 红桃视频成人在线观看| 亚洲精品久久久久久久久久久久| 欧美日本国产在线| 亚洲精品综合精品自拍| 久久亚洲国产精品| 国产精品久久中文| 久久免费成人精品视频| 精品调教chinesegay| 亚洲人成在线观看| 国产精品久久久久久久一区探花| 久久亚洲精品一区| 国模视频一区二区三区| 91在线视频导航| 色综合天天狠天天透天天伊人| 欧美一性一乱一交一视频| 精品日韩美女的视频高清| 欧美亚洲另类激情另类| 欧美成人小视频| 怡红院精品视频| 国产91ⅴ在线精品免费观看| 国产91成人video| 国产ts人妖一区二区三区| 9.1国产丝袜在线观看| 成人伊人精品色xxxx视频| 日韩一区二区三区在线播放| 亚洲人成网站免费播放| 国产成人激情小视频| 亚洲日本欧美中文幕| 伊是香蕉大人久久| 欧美三级欧美成人高清www| 欧美一级视频免费在线观看| 久久久久久久影视| 91超碰caoporn97人人| 成人精品视频在线| 综合136福利视频在线|