10

我还需要在使用 ARC 的 viewDidUnload 中将 IBOutlet 属性设置为 null 吗?

因为它仍然会生成以下评论:

// 释放主视图的所有保留子视图。

4

3 回答 3

13

好吧,nilling outlet 的主要目的是不创建僵尸,泄漏和奇怪的情况,当子视图没有超级视图时,当视图从视图控制器卸载时可能发生。

现在使用最新版本的 Xcode,如果您在标题内或私有声明中拖动视图元素,它会自动将 Outlet 设置为弱(针对 iOS>=5),并且在这种情况下viewDidUnload它可能会编写的方法[self setYourOutlet:nil];是不必要的,但这是一个很好的做法。如果您需要针对较低的ioses,因为您不能使用弱引用。我建议总是使用,因为这是一个好习惯。

更新

我想完成答案以避免误解(仅谈论iOS5)注意IB仅在主视图的子视图时才将出口设置为弱。通常它发生在包含来自视图控制器的视图的 xib 中。

有时可能会发生,您需要在运行时根据某些条件交换两个视图,而无需以编程方式或在不同的 xib 中创建它们。例如,您的主视图由 vc 拥有,并且在同一个 xib 中您创建了另外两个在那个时候没有超级视图的视图。如果您尝试使用相同的技术将它们连接起来,则创建的参考将是strong. 在运行时,您现在可以交换视图,只需在超级视图中添加或删除,当然您应该在viewDidUnload.

于 2012-05-17T15:17:47.713 回答
11

我将在这里扩展 Andrea 的答案(为他投票!)因为答案并不直接,除非您只指 UI 组件,在这种情况下它们应该很弱。

IBOutlets 是你定义的任何东西。如果您使用:

@property (nonatomic, strong) IBOutlet UIView *someView;

卸载父视图/窗口时,您应该将其设为 nil。

如果你这样做:

@property (nonatomic, weak) IBOutlet __weak UIView *someView;

您不必为零变量,因为它将自动归零。

你如何零完全取决于你。在 ARC 之前,我使用过:

[someView_ release], someView_ = nil;

现在您有两个选择:使用 setter(使用 with 创建@synthesize)或直接设置底层 ivar。结果是相同的——在这两种情况下,对象的生命周期限定符都会记录它的最终使用并释放它。

所以,继续这样做:

self.someView = nil

或者

@synthesize someView = someView_;
...
someView_ = nil;
于 2012-05-17T16:10:55.680 回答
2

对于标记为强的 IBOutlets,您仍然希望在 viewDidUnload 中将它们清零。

为什么:

当您收到内存不足通知时,当前不可见的任何视图都可能会自行卸载(调用 viewDidUnload)以节省内存。通过取消您的网点,您将放弃所有权并让它们被释放。当再次加载视图时(再次显示时),将再次设置出口并调用 viewDidLoad。

于 2012-05-17T16:23:27.673 回答