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



在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;
}
}

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

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

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

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

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

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
}

最新更新