Iphone DID接收内存警告、查看DID卸载和解除锁定

Iphone DID接收内存警告、查看DID卸载和解除锁定,iphone,memory-management,uiviewcontroller,Iphone,Memory Management,Uiviewcontroller,我已经浏览了很多帖子,我的书和苹果开发者,并且收集了我需要的关于使用它们的大部分理解。如果有好心人能证实我做得对(或纠正我),并回答这两个问题,我将不胜感激 非常感谢, 克里斯 消息的顺序 通常,消息将按以下顺序显示: 我收到了记忆警告 viewDidUnload(可能由1引起)-显然只适用于视图控制器类 解除锁定 没有收到记忆警告 当系统内存不足时调用 默认情况下,视图控制器注册为内存警告通知,在模板方法中,如果没有superview,则调用[super didReceiveMemoryW

我已经浏览了很多帖子,我的书和苹果开发者,并且收集了我需要的关于使用它们的大部分理解。如果有好心人能证实我做得对(或纠正我),并回答这两个问题,我将不胜感激

非常感谢,

克里斯

消息的顺序 通常,消息将按以下顺序显示:

  • 我收到了记忆警告

  • viewDidUnload(可能由1引起)-显然只适用于视图控制器类

  • 解除锁定

没有收到记忆警告

当系统内存不足时调用

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

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

问题1-即使视图可见,也会调用此命令,因此很难看到可以安全释放的内容。了解这一点以及一些可以发布的示例将非常有帮助

viewDidUnload

每当不可见视图控制器的View属性设置为nil时调用,手动或最常见的方式是通过didReceiveMemoryWarning

viewDidUnload方法存在,因此您可以: -清理任何你想要的东西,以节省额外的内存或时间 -如果您保留了一些iboutlet,则可以帮助释放内存,而这些内存本来不会被卸载的视图释放

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

解除锁定

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

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

弹出视图控制器和内存


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

一些更正和建议:

  • 确实收到了记忆警告
    实践
正如您所说,控制器的默认实现
didReceiveMemoryWarning
会在“安全的情况下”释放其视图。虽然从苹果的文档中还不清楚“这样做安全”是什么意思,但人们普遍认为它没有superview(因此当前无法看到该视图),而且它的
loadView
方法可以毫无问题地重建整个视图

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

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

因此,在您的
didReceiveMemoryWarning
中,首先调用超类实现,如果其视图已卸载,则释放自定义数据,因为您知道
loadView
viewDidLoad
肯定会再次调用。比如说,

- (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
假定某人需要该视图,并将立即再次加载该视图

  • viewDidUnload
    方法
viewDidUnload
在视图控制器由于内存警告而卸载视图时调用。例如,如果从superview中删除视图,并将控制器的
view
属性设置为
nil
viewDidUnload
方法将被调用。微妙的一点是,即使在控制器接收到
didReceiveMemoryWarning
时视图控制器的视图已经被释放并设置为零,那么实际上控制器没有要卸载的视图,如果调用超类的
didReceiveMemoryWarning
实现,则将调用
viewDidUnload

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

  • 弹出视图控制器
如果您的意思是通过“弹出”来“从superview中删除”,则会减少视图的保留计数,但不一定取消分配

如果您的意思是从UINavigationController中弹出,那么它实际上会减少视图控制器本身的保留计数。如果视图控制器没有被另一个对象保留,它将被解除分配,最好是与其视图一起释放。正如我所解释的,
viewDidUnload
这次将不被调用

  • 其他
从技术上讲,保留计数可能不会降至零。对象更有可能只是被释放,而不事先将计数设置为零

为了确保这一点,视图控制器本身