【问题标题】:What is the proper way to unload views in iOS 6 in a memory warning (Apple doc flaw)?在内存警告(Apple doc 缺陷)中卸载 iOS 6 中的视图的正确方法是什么?
【发布时间】:2012-09-14 12:10:09
【问题描述】:

在 iOS 6 中,viewWillUnloadviewDidUnload 已弃用,并且 UIViewController 在内存警告期间不再卸载屏幕上不可见的视图。 View Controller Programming Guide 有一个如何手动恢复此行为的示例。

这是代码示例:

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Add code to clean up any of your own resources that are no longer necessary.
    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;
    }
}

代码示例下面是以下注释:

下次访问视图属性时,会重新加载视图 和第一次完全一样。

这里有一个明显的缺陷。如果尚未加载其视图的视图控制器收到内存警告,它将在if ([self.view window] == nil) 行中加载其视图,然后继续清理并再次释放它。充其量,这是低效的。在最坏的情况下,如果加载了复杂的视图层次结构和支持数据,它会使内存条件变得更糟。我在 iOS 模拟器中验证了这种行为。

我当然可以对此进行编码,但对于 Apple 文档来说,出现这样的错误似乎很奇怪。我错过了什么吗?

【问题讨论】:

    标签: uiviewcontroller ios6 didreceivememorywarning


    【解决方案1】:

    在视图控制器中正确检查正在加载和显示在屏幕上的视图是:

    if ([self isViewLoaded] && [self.view window] == nil)

    我在 iOS 6 中使用类似于 iOS 5 的视图控制器卸载视图和清理的完整解决方案如下:

    // will not be called in iOS 6, see iOS docs
    - (void)viewWillUnload
    {
      [super viewWillUnload];
      [self my_viewWillUnload];
    }
    
    // will not be called in iOS 6, see iOS docs
    - (void)viewDidUnload
    {
      [super viewDidUnload];
      [self my_viewDidUnload];
    }
    
    // in iOS 6, view is no longer unloaded so do it manually
    - (void)didReceiveMemoryWarning
    {
      [super didReceiveMemoryWarning];
      if ([self isViewLoaded] && [self.view window] == nil) {
        [self my_viewWillUnload];
        self.view = nil;
        [self my_viewDidUnload];
      }
    }
    
    - (void)my_viewWillUnload
    {
      // prepare to unload view
    }
    
    - (void)my_viewDidUnload
    {
      // the view is unloaded, clean up as normal
    }
    

    【讨论】:

    • viewDidUnloadviewWillUnload 是否用于向后兼容?如果是这样,我建议将代码注释为在 iOS 6 中根本不会调用这两个方法(作为UIViewController docs 状态)。
    • 如果您可以在- didReceiveMemoryWarning 中相应地调用[self viewWillUnload][self viewDidUnload] 而不是自定义- my_view{Will|Did}Unload,那会不会更好?
    • 应该没问题。 B/c 这些方法由 iOS viewWillUnload 和 viewDidUnload 会更简单。 my_XXX 命名约定是任意的,您可以随意命名(当然)。
    • @XJones,在iOS5中,my_viewWillUnload和my_viewDidUnload好像会被调用两次
    • 不在我的测试中。在 iOS5 中,viewWillUnloadviewDidUnload 首先被调用,一旦视图被卸载,my_viewXXXUnload 版本不会被调用 b/c if 子句中的条件失败。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-02
    • 2013-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    相关资源
    最近更新 更多