11

在 iOS 6 中,viewWillUnload并且viewDidUnload已弃用,并且 UIViewControllers 不再卸载在内存警告期间在屏幕上不可见的视图。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 文档来说,出现这样的错误似乎很奇怪。我错过了什么吗?

4

1 回答 1

17

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

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
}
于 2012-09-22T15:22:37.717 回答