1. 程式人生 > >IOS didReceiveMemoryWarning 的那些事

IOS didReceiveMemoryWarning 的那些事

根據網上的說法進行總結:

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也不會被呼叫了。


    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.                [super viewDidUnload];  
  11.        }  
 

但是到了ios6.0之後,這裡又有所變化,ios6.0記憶體警告的viewDidUnload 被遮蔽,即又回到了ios3.0的時期的記憶體管理方式。   

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函式。
             }

           }
    }

根據網上的的翻譯理解是這樣的.一般不是官方的說法本人都會保留懷疑的態度.然後找到了官方的連結.

在IOS6過後,有這樣一段話.

On iOS 6 and Later, a View Controller Unloads Its Own Views When Desired

The default behavior for a view controller is to load its view hierarchy when the view property is first accessed and thereafter keep it in memory until the view controller is disposed of. The memory used by a view to draw itself onscreen is potentially quite large. However, the system automatically releases these expensive resources when the view is not attached to a window. The remaining memory used by most views is small enough that it is not worth it for the system to automatically purge and recreate the view hierarchy.

You can explicitly release the view hierarchy if that additional memory is necessary for your app. Listing 4-3 overrides the method to accomplish this. First, is calls the superclass’s implementation to get any required default behavior. Then, it cleans up the view controller’s resources. Finally, it tests to see if the view controller’s view is not onscreen. If the view is associated with a window, then it cleans up any of the view controller’s strong references to the view and its subviews. If the views stored data that needs to be recreated, the implementation of this method should save that data before releasing any of the references to those views.


這段話的大概意思是,當view被繪製在螢幕上的時候,是最費資源的,然後系統在記憶體警告的時候,會自動把這個資源給清理掉.
然後,就會剩下一小部分資源,通常這小部分資源可以不去處理他.
如果有一定的情況要去處理掉...就可以繼承didReceiveMemoryWarning這個類來處理.

所以說,在IOS6版本之後,就可以不用去管這塊東西了.(特殊情況除外).