為什么viewDidUnload 被棄用
- iOS4 和 iOS5系統中,當內存不足,引用收到 MemoryWarning 時候,系統會自動調用當前界面上的 Viewontroller 的 viewDidUnload 方法,通常情況下,這些未顯示咋界面上的 Controller 是 UINavigationController Push 棧中未在棧頂的 Controller,以及 UITabBarViewController 中未顯示的子 ViewController,這些 Controller 都會在 MemoryWarning 事件發生的時候,讓系統自動調用 viewDidUnload 方法。
- 在 iOS6中,由于 viewDidunload 事件在任何情況下都不會被處罰,所以蘋果在文檔中建議,應該將回收內存的相關操作移到另一個回調函數 didReceiveMemoryWarning 中,但是如果你以為僅僅是把以前寫到 ViewDidUnload 函數中的代碼移動到 didReceiveMemoryWarning 函數中,那么就錯了。
- 在 iOS6以后的版本中不建議將 view 置為 nil 的原因如下:
- UIView 有一個 CALayer 的成員變量,CALayer 是具體用于將自己滑到屏幕上的
- CALayer 是一個 bitmap 圖像的容器類,當 UIView 調用自身的 drawRect 時候,CALayer 才會創建這個 bitmap 圖像類。
- 具體占內存的其實是一個 bitmap 圖像類,CALayer 只占48bytes,UIView 只占有96Bytes,而一個 iPad 的全屏 UIVIew 的 bitmap 類會占到12MB 的大小。
- 在 iOS6中,當系統發出 MemoryWarning 時候,系統會自動回收 bitmap 類,但是不回收 UIView 和 CALayer 類,這樣既能回收大部分內存,又能在需要 bitmap 類的時候,通過調用 UIView 的 drawRect:方法重建。
內存優化
- 蘋果對上面的內存回收做了一個優化:
- 當一段內存被分配時候,他會被標記成“In use”,以防止被重復使用,當內存被釋放的時候,這段內存會被標記成“Not in use”,這樣,在有新的內存申請時,這塊內存就可能被分配給其他變量。
- CALayer 包括具體的 bitmap 內存的私有成員變量類型為 CABackStore,當收到 MemoryWarning 時候, CABackStore類型的內存區會被標記成 volatile 類型,volatile 表示,這塊內存可能再次被元變量使用。
- 這樣,有了上面的優化之后,當收到 MemoryWarning 的時候,雖然所有的 CALayer 所包含的 bitmap 內存都被標記成 volatile 了,但是只要這塊內存沒有被復用,當需要重建 bitmap 內存時候,它就可以直接被復用,而避免了再次調用 UIView 的 drawRect: 方法。
- 所以 ,簡單來說,對于 iOS6,不需要做任何以前 viewDidUnload 做的事事情,更不需要把以前 viewDidUnload 的代碼移動到 didReceiveMemoryWarning 方法中。