didReceiveMemoryWarning,viewDidUnload和dealloc [英] didReceiveMemoryWarning, viewDidUnload and dealloc

查看:116
本文介绍了didReceiveMemoryWarning,viewDidUnload和dealloc的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我查看过很多帖子,我的书籍和Apple开发人员,并收集了大部分使用这些内容所需的理解。如果某个善良的人能够证实我做对了(或纠正了我)并回答了这两个问题,我将非常感激。

I've looked through lots of posts, my books and Apple Developer and gleaned most of the understanding I need on use of these. I would be really grateful if some kind person could confirm that I've got it right (or correct me) and also answer the two questions.

非常感谢,

Chris。

消息顺序
通常,消息会出现按以下顺序:

Order of Messages Generally, the messages will appear in the following order:


  • didReceiveMemoryWarning

  • didReceiveMemoryWarning

viewDidUnload (可能由1引起) - 显然只适用于View Controller类。

viewDidUnload (which can be caused by 1) - obviously only applies to View Controller Classes.

dealloc

didReceiveMemoryWarning

当系统内存不足时调用。

Called when the system is low on memory.

默认情况下,视图控制器已注册内存警告通知,在模板方法中,如果没有superview,对[super didReceiveMemoryWarning]的调用会释放视图,这是一种检查视图是否可见的方法。它通过将其属性设置为nil来释放视图。

By default, view controllers are registered for memory warning notifications and within the template method, the call to [super didReceiveMemoryWarning] releases the view if it doesn't have a superview, which is a way of checking whether the view is visible or not. It releases the view by setting its property to nil.

操作 - 释放您不需要的任何内容,可能会撤消您在viewDidLoad中设置的内容。不要释放UI元素,因为这些元素应该由viewDidUnload释放。

Action - Release anything you do not need, likely to be undoing what you might have set up in viewDidLoad. Do not release UI elements as these should be released by viewDidUnload.

问题1 - 即使视图可见,它似乎也会被调用,因此很难看看你能安全释放什么。理解这个以及可以发布的一些例子真的很有帮助。

viewDidUnload

每当不可见的View Controller的View属性设置为nil时调用,手动或最常通过didReceiveMemoryWarning。

Called whenever a non visible View Controller's View property is set to nil, either manually or most commonly through didReceiveMemoryWarning.

viewDidUnload方法是那么你可以:
- 清理你想要的任何其他东西,以节省额外的内存或
- 如果你保留了一些IBOutlets,以帮助释放原本不会被释放的内存正在卸载的视图。

The viewDidUnload method is there so that you can: - clean up anything else you would like, to save extra memory or - if you've retained some IBOutlets, to help free up memory that wouldn't otherwise be released by the view being unloaded.

操作 - 通常在dealloc中释放的任何IBOutlet也应该在此方法中释放(并且引用设置为nil)。请注意,如果属性设置为retain,则将它们设置为nil也会释放它们。

Action - generally any IBOutlets you release in dealloc, should also be released (and references set to nil) in this method. Note that if the properties are set to retain, then setting them to nil will also release them.

dealloc

取消分配视图控制器对象时调用,当保留计数降至零时将调用。

Called when the view controller object is de-allocated, which it will be when the retain count drops to zero.

操作 - 释放所有该类保留的对象,包括但不限于具有保留或复制的所有属性。

Action - release all objects that have been retained by the class, including but not limited to all properties with a retain or copy.

弹出视图控制器和内存

问题2 - 弹出视图会将其从内存中删除吗?

推荐答案

一些更正和建议:


  • didReceiveMemoryWarning 做法

  • didReceiveMemoryWarning practices

正如您所说,控制器的默认实现 didReceiveMemoryWarning 会释放其视图这样做是安全的。虽然从Apple的文档中不清楚安全这样做是什么意思,但它通常被认为没有超级视图(因此目前无法看到视图),以及它的 loadView 方法可以毫无问题地重建整个视图。

As you said, the controller's default implementation of didReceiveMemoryWarning releases its view if it is 'safe to do so'. While it's not clear from Apple's documents what 'safe to do so' means, it is generally recognized as it has no superview (thus there is no way that the view is currently visible), and its loadView method can rebuild the entire view without problems.

覆盖 didReceiveMemoryWarning 时的最佳做法是,根本不尝试释放任何视图对象。如果不再需要,只需发布​​您的自定义数据即可。关于视图,只需让超类的实现处理它们。

The best practice when you override didReceiveMemoryWarning is, not to try releasing any view objects at all. Just release your custom data, if it is no longer necessary. Regarding views, just let the superclass's implementation deal with them.

但是,有时,数据的必要性可能取决于视图的状态。在大多数情况下,这些自定义数据是在 viewDidLoad 方法中设置的。在这些情况下,安全发布自定义数据意味着您知道 loadView viewDidLoad 将在之前调用视图控制器再次使用自定义数据。

Sometimes, however, the necessity of the data may depend on the state of your view. In most cases, those custom data is set in viewDidLoad method. In these cases, 'safe to release custom data' means that you know that loadView and viewDidLoad will be invoked before the view controller uses the custom data again.

因此,在 didReceiveMemoryWarning 中,首先调用超类实现,如果是它的视图被卸载,然后释放自定义数据,因为你知道 loadView viewDidLoad 将再次被调用。例如,

Therefore, in your didReceiveMemoryWarning, call the superclass implementation first, and if its view is unloaded, then release the custom data because you know that loadView and viewDidLoad will be invoked again for sure. For example,

- (void)didReceiveMemoryWarning {
    /* This is the view controller's method */
    [super didReceiveMemoryWarning];
    if (![self isViewLoaded]) {
        /* release your custom data which will be rebuilt in loadView or viewDidLoad */
    }
}

小心不要使用 self.view == nil ,因为 self.view 假设某人需要该视图,并会立即再次加载视图。

Be careful not to use self.view == nil, because self.view assumes that the view is needed for someone and will immediately load the view again.


  • viewDidUnload method

  • viewDidUnload method

viewDidUnload 视图控制器由于内存警告而卸载视图时,会调用c $ c>。例如,如果从超级视图中删除视图并将控制器的视图属性设置为 nil viewDidUnload 方法将被调用。一个微妙的观点是,即使视图控制器的视图已经被释放并且在控制器收到 didReceiveMemoryWarning 时设置为nil,所以实际上没有视图可以卸载如果调用超类的 didReceiveMemoryWarning 的实现,将调用控制器 viewDidUnload

viewDidUnload is called when the view controller unloaded the view due to a memory warning. For example, if you remove the view from the superview and set the view property of the controller to nil, viewDidUnload method will not be invoked. A subtle point is that even if the view of a view controller is already released and set to nil by the time the controller receives didReceiveMemoryWarning, so actually there is no view to unload for the controller, viewDidUnload will be invoked if you call the superclass's implementation of didReceiveMemoryWarning.

这就是为什么将视图控制器的视图属性手动设置为nil不是一个好习惯。如果这样做,您最好还发送 viewDidUnload 消息。我想你对 viewDidUnload 的理解是更理想的,但显然它不是当前的行为。

That's why it's not a good practice to manually set the view property of a view controller to nil. If you do, you may better send a viewDidUnload message as well. I guess your understanding of viewDidUnload is more desirable, but apparently it's not the current behavior.


  • 弹出视图控制器

如果你意味着'通过'弹出'从超级视图中删除',它确实减少了视图的保留计数,但不一定要取消分配它。

If you mean 'removing from the superview' by 'popping', it does decrease the retain count of the view, but not necessarily deallocate it.

如果你的意思是从一个弹出UINavigationController,它实际上减少了视图控制器本身的保留计数。如果视图控制器未被另一个对象保留,则它将被取消分配,最好是其视图。正如我解释的那样, viewDidUnload 这次将

If you mean popping out from a UINavigationController, it actually decrease the retain count of the view controller itself. If the view controller is not retained by another object, it will be deallocated, desirably with its view. As I explained, viewDidUnload will not be invoked this time.


  • 其他......

从技术上讲,保留计数可能不会降至零。如果不事先将计数设置为零,则更有可能仅释放对象。

Technically, the retain count may not go down to zero. The object is more likely to be just deallocated without setting the count to zero beforehand.

为了确保,由于内存警告,视图控制器本身通常不会被默认行为释放。

Just to make sure, the view controller itself is normally not deallocated by default behaviors due to the memory warning.

这篇关于didReceiveMemoryWarning,viewDidUnload和dealloc的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆