iPhone下每个app可用的内存是被限制的,如果一个app使用的内存超过20M,则系统会向该app发送Memory Warning消息。收到此消息后,app必须正确处理,否则可能出错或者出现内存泄露。
app收到Memory Warning后会调用:UIApplication::didReceiveMemoryWarning -> UIApplicationDelegate::applicationDidReceiveMemoryWarning,然后调用当前所有的viewController进行处理。因此处理的主要工作是在viewController。
iOS3-iOS5.0:
调用didReceiveMemoryWarning内调用super的didReceiveMemoryWarning会将controller的view进行释放。所以我们不能将controller的view再次释放。
当系统内存不足时,首先UIViewController的didReceiveMemoryWarining 方法会被调用,而didReceiveMemoryWarining 会判断当前ViewController的view是否显示在window上,如果没有显示在window上,则didReceiveMemoryWarining 会自动将viewcontroller 的view以及其所有子view全部销毁,然后调用viewcontroller的viewdidunload方法。如果当前UIViewController的view显示在window上,则不销毁该viewcontroller的view,当然,viewDidunload也不会被调用了。
iOS6 以后:
调用didReceiveMemoryWarning内调用super的didReceiveMemoryWarning调只是释放controller的resouse,不会释放view
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而费力回收内存。
iOS 6 以后,内存警告回收的是UIResponder 的成员变量CALayer(即一个bitmap图象的包装类),其占内存最多