iOS 6 - viewDidUnload迁移到didReceiveMemoryWarning?

Dev*_*fly 33 ios

因此,viewDidUnload从iOS 6开始不推荐使用,我现在需要做什么?

删除它,并将其中的所有内容迁移didReceiveMemoryWarning或保留,并且不执行任何操作didReceiveMemoryWarning

Rob*_*Rob 68

简短的回答是,在许多情况下,您不需要改变任何东西.而且,你肯定做希望简单地迁移所有的内容viewDidUnloaddidReceiveMemoryWarning.

一般来说,我们大多数人都会设置IBOutletnilin 的引用viewDidUnload(很大程度上是因为Interface Builder会把它放在那里)并执行一般的内存释放(例如清除缓存,释放容易重新创建的模型数据等)didReceiveMemoryWarning.如果这是你的方式,那么你可能不需要任何代码更改.

根据iOS 6 viewDidUnload文档:

在低内存条件下不再清除视图,因此永远不会调用此方法.

因此,您希望将IBOutlet引用的设置移动到nil任何位置,因为不再清除视图.这将毫无意义将它们设置为nildidReceiveMemoryWarning或类似的东西.

但是,如果你通过释放容易重新创建的模型对象,清空缓存等来响应低内存事件viewDidUnload,那么那些东西肯定会转移到didReceiveMemoryWarning.但是,我们大多数人已经在那里已经拥有它了.

最后,如果您释放任何内容didReceiveMemoryWarning,只需确保您的代码不依赖于在viewDidLoad弹出时再次重新创建它们,因为不会调用它(因为视图本身从未被卸载).

正如applefreak所说,这取决于你在做什么viewDidUnload.如果您使用明确的示例来更新您的问题viewDidUnload,我们可能会提供较少的抽象建议.


auc*_*uco 61

简短的回答:

切勿使用-didReceiveMemoryWarning进行平衡拆卸,因为它可能永远或多次调用.如果您在-viewDidLoad中进行了设置,请将清理代码放在-dealloc中.


答案很长:

给出一般答案并不容易,因为它实际上取决于具体情况.但是,有两个重要事实要说明:

1. -viewDidUnload已弃用,实际上从未以iOS6及更高版本开始调用.因此,如果您有清理代码,那么您的应用程序会在这些操作系统版本下泄漏

2. -didReceiveMemoryWarning可能被多次调用或从不调用.因此,对于您在其他地方创建的对象的平衡拆卸,这是一个非常糟糕的地方

我的回答是查看您使用属性的常见情况,例如:

@property (strong) UIView *myCustomView  // <-- this is what I'm talking about
@property (assign) id *myDelegate
Run Code Online (Sandbox Code Playgroud)

在这里你必须做一些清理工作,因为你创建并拥有了自己创建的customView或InterfaceBuilder,但你保留它.在iOS 6之前你可能会做这样的事情:

- (void)viewDidLoad {
    self.myCustomView = [[UIView alloc] initWithFrame:…];
}
- (void)viewDidUnload {  // <-- deprecated!
    [myCustomView removeFromSuperView];
    self.myCustomView = nil;
}
Run Code Online (Sandbox Code Playgroud)

...因为(再次)myCustomView是一个保留属性,由您创建并拥有,因此您必须小心并在结束时"释放"它(将其设置为零).

使用iOS 6,可能是替换-viewDidUnload和将保留属性设置为nil 的最佳位置-dealloc.还有viewWillAppearviewDidDisappear,但这些不依赖于你的视图/控制器的生命周期,但显示周期(在另一方面,-...出现方法是完美的非/注册通知监听!).因此,在每次显示之前和之后创建和销毁视图可能都不合适.dealloc是唯一可以确保在控制器生命周期结束时调用的方法.请注意,[super dealloc]如果您使用ARC,则不得致电:

- (void)dealloc {
    self.myCustomView = nil;
}
Run Code Online (Sandbox Code Playgroud)

但是,如果您正在使用viewDidLoad一些可在低内存条件下释放的视图相关设置,则显示如何处理低内存情况的其他帖子完全有效.在这种情况下,您也可以使用dealloc,但是您必须检查您的视图是否仍然存在.

ViewController的生命周期

也许查看ViewController的一般生命周期也很有帮助:

这是viewController的生命周期(斜体线表示这些方法可能被多次调用):

  • init:加载ViewController,没有可用的接口元素(IBOutlet)(全部为零)
  • viewDidLoad:已加载nib/storyboard,并且所有对象都可用.用户还没有看到任何内容
  • viewWillAppear:即将显示视图
  • viewDidAppear:视图在屏幕上
  • viewWillDisappear:视图即将消失
  • viewDidDisappear:视图刚从窗口取下
  • viewDidUnload:从未在iOS6/7中调用过
  • didReceiveMemoryWarning:你不知道调用它的时间,时间和频率.在iOS6之前它可能会卸载视图,在iOS6之后它只是清除屏幕外缓存或什么都不做
  • dealloc:viewController即将被销毁

所以,总结一下,有各种各样的可能性; 什么去现在真正取决于什么是初始化在哪里:

  • -dealloc如果在-init中创建:或-viewDidLoad:
  • -viewWill/DidDisappear(与-viewWill/DidAppear配对)
  • -didReceiveMemoryWarning(可能会也可能不会被调用)


Jon*_*nas 7

如果您需要知道您的UIViewController是否正在解雇,您可以将此代码添加到viewWillDisappear:

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    if ([self isBeingDismissed] || [self isMovingFromParentViewController])
    {
        // Do your viewDidUnload stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

它不会在viewDidUnload在视图控制器生命周期中执行过一次的同时调用,但在大多数情况下可以满足您的需求!