UIApplication::didReceiveMemoryWarning -> UIApplicationDelegate::applicationDidReceiveMemoryWarning, 然后调用当前所有的viewController进行处理。因此处理的主要工作是在viewController中。
当一个controller收到内存警告时,需要释放一些当前不需要用到却能在需要时重新创建的资源。一个最明显的就是controller's view。以下是文档中关于收到low-memory时的处理流程:
1. The app receives a low-memory warning from the system.
2. Each view controller calls its didReceiveMemoryWarning method. If you override this method, you should use it to release any memory or objects that your view controller object no longer needs. Do not use it to release your view controller’s view. You must call super at some point in your implementation to ensure that the default implementation runs. The default implementation attempts to release the view.
3. If the view cannot be safely released (for example, it is visible onscreen), the default implementation returns.
4. The view controller calls its viewWillUnload method to inform subclasses that the views are about to be removed. A subclass typically overrides the viewWillUnload method when it needs to save any view properties before the views are destroyed.
5. It sets its view property to nil.
6.
The view controller calls its viewDidUnload method to inform subclasses that the views were removed. A subclass typically uses this method to release any strong references it has to those views.
You can use the viewDidUnload method to deallocate any data that is view specific and that can be re-created easily enough if the view is loaded into memory again. If re-creating the data might be too time-consuming, though, you do not have to release the corresponding data objects here. Instead, you should consider releasing those objects in your didReceiveMemoryWarning method.
Use this method to deallocate all noncritical custom data structures associated with your view controller. Although you would not use this method to release references to view objects, you might use it to release any view-related data structures that you did not already release in your viewDidUnload method. (The view objects themselves should always be released in the viewDidUnload method.)
didReceiveMemoryWarining 会判断当前 ViewController 的 view 是否显示在 window 上,如果没有显示在 window 上,则didReceiveMemoryWarining 会自动将 viewcontroller 的view 以及其所有子 view全部销毁,然后调用 viewcontroller 的 viewdidunload 方法。如果当前 UIViewController 的 view 显示在 window 上,则不销毁该viewcontroller 的 view,当然,viewDidunload 也不会被调用了。
重载didReceiveMemoryWarning时,一定调用这个函数的super实现来允许父类(一般是UIVIewController)释放self.view。self.view释放之后,会调用下面的viewDidUnload函数.也就是说,尽管self.view是被处理了,但是outlets的变量因为被retain过,所以不会被释放,为了解决这个问题,就需要在viewDidUnload中释放这些retain过的outlets变量。通常controller会保存nib文件建立的views的引用,但是也可能会保存着loadView函数创建的对象的引用。最完美的方法是使用合成器方法:
self.myCertainView = nil;
这样合成器会release这个view,如果你没有使用property,那么你得自己显式释放这个view。
iOS6.0及其以后,viewDidUnload不再有用,收到low-memeory时系统不会释放Views。
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时自动加载viewDidLoad
if ([self.view window] == nil)// 是否是正在使用的视图
{
// 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函数。
}
}