在内存警告(Apple doc flaw)中卸载iOS 6中的视图的正确方法是什么?

XJo*_*nes 11 uiviewcontroller didreceivememorywarning ios6

在iOS 6中,viewWillUnloadviewDidUnload已被取消,UIViewControllers不再卸载观点,即内存警告时不显示在屏幕上.该视图控制器编程指南对如何手动还原此行为的一个例子.

这是代码示例:

- (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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

下次访问视图属性时,视图将与第一次完全重新加载.

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

我当然可以编写这个代码,但对于Apple docs来说这样的错误似乎很奇怪.我错过了什么吗?

XJo*_*nes 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
}
Run Code Online (Sandbox Code Playgroud)

  • 可能没问题.B/c这些方法由iOS <6.0调用我希望我的更改尽可能与内部实现完全分离,因此代码路径在任何操作系统版本中都是明确的.此外,一旦我转向仅支持iOS 6+,只需完全删除`viewWillUnload`和`viewDidUnload`就更简单了.`my_XXX`命名约定是任意的,你可以随意命名这些(当然). (3认同)