对于iOS6下viewDidUnload回调的讨论

以前在博客里写过一片文章官方ViewController programming guide 上面说的,在iOS6以后要这样干: Really?,后来接触的更深,发现自己错了。学无止境啊!


大家都知道在iOS6,viewDidUnload回调事件被Deprecated掉了。而在iOS4和iOS5时,当系统收到Memory warning时,会自动调用当前没在界面上的ViewController的viewDidUnload事件。(例如UINavigationController Push栈中未显示的ViewController,又如UITabBarViewController中未显示的子ViewController)

由于viewDidUnload事件在iOS6下任何情况都不会被触发,所以苹果在文档中建议,应该将回收内存的相关操作移到另一个回调函数:didReceiveMemoryWarning 中。


大家讨论了一下应该如何在didReceiveMemoryWarning回收内存,在stackoverflow上搜到的解决方法如下:

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
  
    if ([self isViewLoaded]  &&  !self.view.window)
    {
        [self  setView:nil];
    }
} 

但是似乎这么写相对于以前并不省事。最终我们找到一篇文章,文章中说其实并不值得回收这部分的内存,原因如下:


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而费力回收内存。




你可能感兴趣的:(对于iOS6下viewDidUnload回调的讨论)