因此,viewDidUnload
从 iOS 6 开始已弃用,我现在需要做什么?
删除它,将它的所有内容迁移到 中didReceiveMemoryWarning
,或者留下它,不做任何事情didReceiveMemoryWarning
?
因此,viewDidUnload
从 iOS 6 开始已弃用,我现在需要做什么?
删除它,将它的所有内容迁移到 中didReceiveMemoryWarning
,或者留下它,不做任何事情didReceiveMemoryWarning
?
简短的回答是,在许多情况下,您不需要更改任何内容。而且,您当然不想简单地将所有内容迁移viewDidUnload
到didReceiveMemoryWarning
.
通常,我们大多数人都会设置对in的IBOutlet
引用(主要是因为 Interface Builder 会为我们放置它)并在. 如果您就是这样做的,那么您可能不需要任何代码更改。nil
viewDidUnload
didReceiveMemoryWarning
根据 iOS 6viewDidUnload
文档:
在低内存条件下不再清除视图,因此永远不会调用此方法。
因此,您不希望将IBOutlet
引用设置移动到nil
任何地方,因为不再清除视图。将它们设置为nil
indidReceiveMemoryWarning
或类似的东西是没有意义的。
但是,如果您通过viewDidUnload
在didReceiveMemoryWarning
. 但话又说回来,我们大多数人已经在那里有了它。
最后,如果你在 中释放任何东西didReceiveMemoryWarning
,只要确保你的代码在你弹回时不依赖它们被重新创建viewDidLoad
,因为它不会被调用(因为视图本身从未被卸载)。
正如 applefreak 所说,这取决于你在viewDidUnload
. 如果您用您的viewDidUnload
.
简短的回答:
切勿使用 -didReceiveMemoryWarning 进行平衡拆除,因为它可能永远不会或多次调用。如果您在 -viewDidLoad 中进行了设置,请将清理代码放在 -dealloc 中。
长答案:
给出一个笼统的答案并不容易,因为这确实取决于具体情况。但是,有两个重要的事实需要说明:
1. -viewDidUnload 已弃用,实际上从 iOS6 及更高版本开始从未调用过。所以,如果你有你的清理代码,你的应用程序会在这些操作系统版本下泄漏
2. -didReceiveMemoryWarning 可能会被调用多次或从不调用。因此,对于平衡拆解您在其他地方创建的对象来说,这是一个非常糟糕的地方
我的答案是查看您使用属性的常见情况,例如:
@property (strong) UIView *myCustomView // <-- this is what I'm talking about
@property (assign) id *myDelegate
在这里您必须进行一些清理,因为您创建并拥有 customView 或 InterfaceBuilder 创建了它,但您保留了它。在 iOS 6 之前你可能会做这样的事情:
- (void)viewDidLoad {
self.myCustomView = [[UIView alloc] initWithFrame:…];
}
- (void)viewDidUnload { // <-- deprecated!
[myCustomView removeFromSuperView];
self.myCustomView = nil;
}
...因为(再次)myCustomView
是保留的财产,由您创建和拥有,因此您必须小心并在最后“释放”它(将其设置为 nil)。
在 iOS 6 中,替换-viewDidUnload
保留属性并将其设置为 nil 的最佳位置可能是-dealloc
. 还有viewWillAppear
and viewDidDisappear
,但这些与视图/控制器的生命周期无关,而是与显示周期相关(另一方面, -...appear 方法非常适合取消/注册通知侦听器!)。因此,在每次显示之前和之后创建和销毁视图可能并不合适。dealloc
是我们唯一可以确定在控制器生命周期结束时调用的方法。[super dealloc]
请注意,如果您使用 ARC ,则不得调用:
- (void)dealloc {
self.myCustomView = nil;
}
但是,如果您viewDidLoad
用于执行一些可以在内存不足的情况下释放的视图相关设置,那么其他显示如何处理内存不足情况的帖子是完全有效的。在这种情况下,您也可以使用 dealloc,但您必须检查您的视图是否仍然存在。
也许查看 ViewController 的一般生命周期也很有帮助:
这是 viewController 的生命周期(斜体表示这些方法可能会被多次调用):
- init:已加载 ViewController,尚无可用的界面元素(IBOutlet)(全部为零)
- viewDidLoad:nib/storyboard 已经加载,所有对象都可用。用户什么都看不到
- viewWillAppear:即将显示的视图
- viewDidAppear:视图在屏幕上
- viewWillDisappear:视图即将消失
- viewDidDisappear:刚刚从窗口中取出的视图
- viewDidUnload:在 iOS6/7 中从不调用
- didReceiveMemoryWarning:您不知道是否、何时以及多久调用一次。在 iOS6 之前它可能会卸载视图,在 iOS6 之后它只是清除屏幕外缓存或什么都不做
- dealloc:viewController 即将被销毁
因此,总结起来有多种可能性;现在去哪里真的取决于在哪里初始化了什么:
如果您需要知道您的 UIViewController 是否正在关闭,您可以将此代码添加到您的 viewWillDisappear:
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
if ([self isBeingDismissed] || [self isMovingFromParentViewController])
{
// Do your viewDidUnload stuff
}
}
它不会与 viewDidUnload 在视图控制器生命周期中同时调用一次,但在大多数情况下可以满足您的需要!
取决于您在做什么,viewDidUnload
但您可以使用didReceiveMemoryWarning
或dealloc
发布数据。看到这个。
在大多数典型情况下,可以使用此方法代替旧的 viewDidUnload。
// The completion handler, if provided, will be invoked after the dismissed controller's viewDidDisappear: callback is invoked.
- (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^)(void))completion NS_AVAILABLE_IOS(5_0);
Swift 2017 语法:
override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
if (yourChildViewController != nil) {
print("good thing we did this!")
}
yourChildViewControllerProperty = nil
super.dismiss(animated: flag, completion: completion)
}