iOS6.0以后App對內存警告的處理


iOS的版本號已經到了6.0.1了,  這篇文章說60%的iPhone用戶已經升級到了iOS6了。那我們的應用有沒有做好相關的准備工作呢。
 
   今天在調試代碼的時候,用模擬器模擬內存警告,結果發現自己的ViewController竟然不響應viewDidUnload函數,尼瑪,這可是個大問題。
 
   查詢文檔,iOS升級到6.0以后,不再支持viewDidUnload了。官方文檔的解釋是系統會自動控制大的View所占用的內存,其他小的View所占用的內存是極其微小的,不值得為了省內存而去清理然后在重新創建。如果你需要在內存警告的時候釋放業務數據或者做些其他的特定處理,你可以實現 didReceiveMemoryWarning 這個函數。 蘋果官方文檔請猛擊
 
  總結下:iOS6 之前:
                          viewDidUnload  和 didReceiveMemoryWarning 都會被調用。
             iOS6 及其后面的版本。
                          viewDidUnload 不會被調用  didReceiveMemoryWarning 依然被調用。系統會自動處理view相關的內存,我們不用擔心。
 
     蘋果官方給出的解釋了相關的方案總是看起來十分美好的,但是現實往往是殘酷。
 
1.我們的工程是ARC的。
2.我們會在viewController里面持有大量子view的成員變量(strong)
3.我們實現了大量的viewDidUnload函數來釋放 (2)里面持有的那個子view。
 
    讓我們看看我們的代碼到了iOS6以后會發生什么事情。因為所有的子view都是strong持有的,這樣會導致,及時系統內存警告導致了view的回收,他們也不會被真正的釋放。於是乎,我們的程序可能就在后台被系統頻繁的殺死。
 
    分析到這里,解決方案也就很清楚了,我就不羅嗦了。貼段Apple給的解決方案代碼。
 1 - (void)didReceiveMemoryWarning  
 2 {  
 3     [super didReceiveMemoryWarning];  
 4     // Add code to clean up any of your own resources that are no longer necessary.  
 5     if ([self.view window] == nil)  
 6     {  
 7         // Add code to preserve data stored in the views that might be  
 8         // needed later.  
 9         // Add code to clean up other strong references to the view in  
10         // the view hierarchy.  
11         self.view = nil;  
12     }  
那么有了上面的代碼,事情結束了嗎?沒有。下面說下這個方案的問題。(一個例子)
 
    一個App 有 3個 tab,A 、B、C。(都從viewController繼承,並且都實現了 didReceiveMemoryWarning)。當程序啟動的時候,默認顯示tab A,這個時候,A 的 viewDidload被調用,並且加載數據顯示給用戶。然后我們切換到 tab B,B會重復A的加載過程。
      這時候系統產生了一個內存警告,A、B、C 3個對象都會受到警告。
 
A對象:因為它已經不在當前UI顯示了,所以滿足 [self.view window] == nil,相關view被釋放。
B對象:正在顯示,所有 didReceiveMemoryWarning什么也不會干。
C對象:最悲慘,從來沒有顯示過,viewDidload從來沒調用過,也沒有顯示過。然后有個self.view .這句的調用會導致一個結果,就是C對象的viewDidload會被調用一次,於是他的邏輯就是釋放前先創建一次,然后再把自己釋放,是不是很悲劇。(所以apple給的方案也不一定完美靠譜)
 
到這里故事也講了,最后說說,在iOS6 及其以后,我們應該怎么處理這個問題。
 
1.不要把 subView 當成成員變量來持有。使用tag來操作。(其實不管在哪個版本最后都這么做)
2.不需要實現viewDidUnload,由系統自己來控制相關的內存釋放
3.在需要的時候實現 didReceiveMemoryWarning來釋放一些業務數據減少內存的占用,不要操作UIView。
 
   也許有錯誤,歡迎大家指正交流


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM