didReceiveMemoryWarning和dealloc之间的关系是什么?

时间:2023-01-23 23:48:44

Will dealloc be called when under memory pressure? If it's true, is it called before didReceiveMemoryWarning or after? Also, when the view controller is being released, is it for sure that dealloc will be called?

在内存压力下会被调用吗?如果是真的,是在didReceiveMemoryWarning之前还是之后调用?此外,当视图控制器被释放时,是否可以调用dealloc?

2 个解决方案

#1


3  

The didReceiveMemoryWarning is simply informing you that you are low in memory. Neither the view nor the controller is released. On the other hand, prior to iOS 6, you might received viewDidUnload at the same time, which is informing you that the view has been removed (but not the view controller). That's why you override didReceiveMemoryWarning, so you can also free up any other stuff that your view controller can safely release. But these low memory situations, the view controller is never released. Worst case scenario, if viewDidUnload was called, the view will be released, but not the controller.

didReceiveMemoryWarning只是告诉你内存不足。视图和控制器都没有被释放。另一方面,在iOS 6之前,您可能会同时收到viewDidUnload,这会通知您视图已被删除(但不是视图控制器)。这就是你重写didReceiveMemoryWarning的原因,所以你也可以释放你的视图控制器可以安全释放的任何其他东西。但是这些低内存情况下,视图控制器永远不会被释放。最糟糕的情况是,如果调用viewDidUnload,视图将被释放,但不会释放控制器。

FYI, I quote from the documentation:

仅供参考,我引用文件:

Memory is a critical resource in iOS, and view controllers provide built-in support for reducing their memory footprint at critical times. The UIViewController class provides some automatic handling of low-memory conditions through its didReceiveMemoryWarning method, which releases unneeded memory.

内存是iOS中的关键资源,视图控制器提供内置支持,以在关键时刻减少内存占用。 UIViewController类通过didReceiveMemoryWarning方法提供一些自动处理低内存条件的方法,该方法释放不需要的内存。

When a low-memory warning occurs, the UIViewController class purges its views if it knows it can reload or recreate them again later. If this happens, [if running iOS versions prior to 6.0] it also calls the viewWillUnload and viewDidUnload methods to give your code a chance to relinquish ownership of any objects that are associated with your view hierarchy, including objects loaded from the nib file, objects created in your viewDidLoad method, and objects created lazily at runtime and added to the view hierarchy.

发生内存不足警告时,如果UIViewController类知道它可以重新加载或稍后再次重新创建它们,则会清除它的视图。如果发生这种情况,[如果运行6.0之前的iOS版本],它还会调用viewWillUnload和viewDidUnload方法,让您的代码有机会放弃与视图层次结构相关联的任何对象的所有权,包括从nib文件加载的对象,对象在viewDidLoad方法中创建,并在运行时延迟创建对象并添加到视图层次结构中。

and

[didReceiveMemoryWarning] is called when the system determines that the amount of available memory is low. The default implementation of this method attempts to release the view controller’s view [in iOS versions prior to 6.0]. To be released, the view must not have a superview; that is, it is not part of a view hierarchy. For more information on how views are unloaded, see “The View Controller Life Cycle”.

当系统确定可用内存量较低时,将调用[didReceiveMemoryWarning]。此方法的默认实现尝试释放视图控制器的视图[在6.0之前的iOS版本中]。要发布,视图必须没有superview;也就是说,它不是视图层次结构的一部分。有关如何卸载视图的更多信息,请参阅“视图控制器生命周期”。

You can override this method to release any additional memory used by your view controller. If you do, your implementation of this method must call the super implementation at some point to allow the view controller to release its view. If your view controller holds references to views in the view hierarchy, you should release those references in the viewDidUnload method instead.

您可以覆盖此方法以释放视图控制器使用的任何其他内存。如果这样做,那么此方法的实现必须在某个时刻调用超级实现,以允许视图控制器释放其视图。如果视图控制器保存对视图层次结构中视图的引用,则应该在viewDidUnload方法中释放这些引用。

Update:

In answer to your other question (which you may not care about now that you realize that view controllers are not, themselves, released when the didReceiveMemoryWarning is invoked), yes, when the item is finally released (and has a retain count of zero, i.e. the alloc and all of the various retains are now offset by corresponding release statements), then dealloc will be invoked.

回答你的另一个问题(你现在可能不在乎你已经意识到视图控制器本身在调用didReceiveMemoryWarning时被释放),是的,当项目最终被释放时(并且保留计数为零,即,alloc和所有各种保留现在由相应的释放语句抵消),然后将调用dealloc。

#2


3  

There is no relationship, didReceiveMemoryWarning is giving you the chance to react to the low memory situation by deleting any un-needed resources.

没有关系,didReceiveMemoryWarning让你有机会通过删除任何不需要的资源来对低内存情况作出反应。

If a view controller, or any other object, is released and its retain count decreases to 0 then it will be deleted and its dealloc will be called.

如果视图控制器或任何其他对象被释放并且其保留计数减少到0,那么它将被删除并且将调用其dealloc。

If an object is released but its retain count does not reduce to 0 then it won't be deleted thus its dealloc won't get called.

如果一个对象被释放但其保留计数没有减少到0那么它将不会被删除,因此它的dealloc将不会被调用。

A dealloc is called when an object is being deleted, deletion and release are not the same thing. An object is deleted when its retain count reaches 0.

当删除对象时,调用dealloc,删除和释放不是同一个东西。当保留计数达到0时,将删除该对象。

#1


3  

The didReceiveMemoryWarning is simply informing you that you are low in memory. Neither the view nor the controller is released. On the other hand, prior to iOS 6, you might received viewDidUnload at the same time, which is informing you that the view has been removed (but not the view controller). That's why you override didReceiveMemoryWarning, so you can also free up any other stuff that your view controller can safely release. But these low memory situations, the view controller is never released. Worst case scenario, if viewDidUnload was called, the view will be released, but not the controller.

didReceiveMemoryWarning只是告诉你内存不足。视图和控制器都没有被释放。另一方面,在iOS 6之前,您可能会同时收到viewDidUnload,这会通知您视图已被删除(但不是视图控制器)。这就是你重写didReceiveMemoryWarning的原因,所以你也可以释放你的视图控制器可以安全释放的任何其他东西。但是这些低内存情况下,视图控制器永远不会被释放。最糟糕的情况是,如果调用viewDidUnload,视图将被释放,但不会释放控制器。

FYI, I quote from the documentation:

仅供参考,我引用文件:

Memory is a critical resource in iOS, and view controllers provide built-in support for reducing their memory footprint at critical times. The UIViewController class provides some automatic handling of low-memory conditions through its didReceiveMemoryWarning method, which releases unneeded memory.

内存是iOS中的关键资源,视图控制器提供内置支持,以在关键时刻减少内存占用。 UIViewController类通过didReceiveMemoryWarning方法提供一些自动处理低内存条件的方法,该方法释放不需要的内存。

When a low-memory warning occurs, the UIViewController class purges its views if it knows it can reload or recreate them again later. If this happens, [if running iOS versions prior to 6.0] it also calls the viewWillUnload and viewDidUnload methods to give your code a chance to relinquish ownership of any objects that are associated with your view hierarchy, including objects loaded from the nib file, objects created in your viewDidLoad method, and objects created lazily at runtime and added to the view hierarchy.

发生内存不足警告时,如果UIViewController类知道它可以重新加载或稍后再次重新创建它们,则会清除它的视图。如果发生这种情况,[如果运行6.0之前的iOS版本],它还会调用viewWillUnload和viewDidUnload方法,让您的代码有机会放弃与视图层次结构相关联的任何对象的所有权,包括从nib文件加载的对象,对象在viewDidLoad方法中创建,并在运行时延迟创建对象并添加到视图层次结构中。

and

[didReceiveMemoryWarning] is called when the system determines that the amount of available memory is low. The default implementation of this method attempts to release the view controller’s view [in iOS versions prior to 6.0]. To be released, the view must not have a superview; that is, it is not part of a view hierarchy. For more information on how views are unloaded, see “The View Controller Life Cycle”.

当系统确定可用内存量较低时,将调用[didReceiveMemoryWarning]。此方法的默认实现尝试释放视图控制器的视图[在6.0之前的iOS版本中]。要发布,视图必须没有superview;也就是说,它不是视图层次结构的一部分。有关如何卸载视图的更多信息,请参阅“视图控制器生命周期”。

You can override this method to release any additional memory used by your view controller. If you do, your implementation of this method must call the super implementation at some point to allow the view controller to release its view. If your view controller holds references to views in the view hierarchy, you should release those references in the viewDidUnload method instead.

您可以覆盖此方法以释放视图控制器使用的任何其他内存。如果这样做,那么此方法的实现必须在某个时刻调用超级实现,以允许视图控制器释放其视图。如果视图控制器保存对视图层次结构中视图的引用,则应该在viewDidUnload方法中释放这些引用。

Update:

In answer to your other question (which you may not care about now that you realize that view controllers are not, themselves, released when the didReceiveMemoryWarning is invoked), yes, when the item is finally released (and has a retain count of zero, i.e. the alloc and all of the various retains are now offset by corresponding release statements), then dealloc will be invoked.

回答你的另一个问题(你现在可能不在乎你已经意识到视图控制器本身在调用didReceiveMemoryWarning时被释放),是的,当项目最终被释放时(并且保留计数为零,即,alloc和所有各种保留现在由相应的释放语句抵消),然后将调用dealloc。

#2


3  

There is no relationship, didReceiveMemoryWarning is giving you the chance to react to the low memory situation by deleting any un-needed resources.

没有关系,didReceiveMemoryWarning让你有机会通过删除任何不需要的资源来对低内存情况作出反应。

If a view controller, or any other object, is released and its retain count decreases to 0 then it will be deleted and its dealloc will be called.

如果视图控制器或任何其他对象被释放并且其保留计数减少到0,那么它将被删除并且将调用其dealloc。

If an object is released but its retain count does not reduce to 0 then it won't be deleted thus its dealloc won't get called.

如果一个对象被释放但其保留计数没有减少到0那么它将不会被删除,因此它的dealloc将不会被调用。

A dealloc is called when an object is being deleted, deletion and release are not the same thing. An object is deleted when its retain count reaches 0.

当删除对象时,调用dealloc,删除和释放不是同一个东西。当保留计数达到0时,将删除该对象。