【问题标题】:IBOutlet and viewDidUnload under ARCARC下的IBOutlet和viewDidUnload
【发布时间】:2011-10-07 01:50:41
【问题描述】:

在 SO here 上有一个与此类似的问题,但我只是想澄清一些在那里没有完全解释的问题。

我知道所有的委托和出口——事实上任何对“父”对象的引用,作为一个好公民并考虑一下对象图——都应该将弱引用归零。由于归零弱指针的性质会在引用对象的保留计数达到零时自动下降到 nil,这是否意味着现在不需要在 viewDidUnload 中将 IBOutlets 设置为 nil?

所以,如果我这样声明我的出口:

@property (nonatomic, weak) IBOutlet UILabel *myLabel;

下面的代码有没有作用?

- (void)viewDidUnload
{
    self.myLabel = nil;

    [super viewDidUnload];
}

【问题讨论】:

  • 我想知道否决票的原因?
  • 我也很好奇这个答案,所以我投了反对票。我不知道答案...

标签: ios weak-references iboutlet automatic-ref-counting


【解决方案1】:

只是做一些研究......

据我了解,weak 类似于 assign,因为它们都是弱引用。

但是,assign 不会创建归零引用。即,如果相关对象被销毁,并且您访问该属性,您将获得 BAD_ACCESS_EXCEPTION

当它引用的对象被销毁时,弱属性会自动归零(= nil)。

在这两种情况下,都没有必要将 property 设置为 nil,因为它不会影响所讨论对象的保留计数。使用保留属性时是必需的。

显然,ARC还引入了一个新的“strong”属性,和“retain”一样?

研究完成here

【讨论】:

  • 感谢您的回复。我了解弱参考的工作原理,我的问题更多与viewDidUnload 的底层机制有关。换句话说,视图是否总是会在 viewDidUnload 调用之后直接强制对 nil 的弱引用?
  • 再一次,据我了解,视图及其子视图将在从显示中移除时被释放。因为,weak 不会增加释放计数,并且在其引用被销毁时归零,所以它不应该是必需的。
  • 对不起,我第一次阅读时一定错过了你的那部分答案。
【解决方案2】:

我做了一些测试,看来viewDidUnload 方法中的代码 是不必要的。为了支持这一点,viewDidUnload 的文档实际上说:

调用此方法时,视图属性为零。

表示弱引用必须已经自动设置为nil

【讨论】:

  • 这也是我的理解。但是为什么 Xcode 在创建弱出口时会在 viewDidUnload 中插入 [self setMySubview:nil] 语句?
  • 我认为它可能是 ARC 之前的代码遗留下来的一个特性,就像你要求 Xcode 为 Core 生成一个 NSManagedObject 子类一样生成的数据属性设置为retain,而不是strong。尽管就网点而言,它们被创建为weak。我的猜测是这是无意的。
  • 我同意。在拖放以在代码中创建 outlet 时,Interface Builder UI 可能会谨慎行事。只要您在相关插座上使用 ARC 和弱引用,就可以安全地删除这些 nil 设置。
【解决方案3】:

我有一些经验证据支持 IBOutlets 确实已经自动设置为 nil。这是我所做的:

  1. 我为我的 IBOutlet 属性 (@synthesize myLabel = myLabel_) 设置了显式 ivars,以便以后可以在调试器中检查它们的值。
  2. 我在viewDidUnload 的第一行启用了一个断点。
  3. 我通过模拟内存警告来安排viewDidUnload 被调用。
  4. 我检查了与我的 IBOutlet 属性关联的显式 ivars 的值。

显式 ivars 都以 nil 作为它们的值,然后我到达断点。

【讨论】:

    【解决方案4】:

    根据我对如果您使用弱引用在 ARC 中如何管理 outlet 的理解,您不需要向 viewDidUnload 添加任何内容,因为它已经为零。因此,这样做是多余的。

    但是,如果您确实有强大的插座,如果您指向 nib 中的顶级项目,Apple 说您应该这样做,那么您绝对应该继续在 viewDidUnload 中添加适当的行以消除这些。

    【讨论】:

    • 我想知道,如果我定义了这个@property (nonatomic, strong) IBOutlet UILabel *myLabel;,我是否需要在函数viewDidUnload中定义self.myLabel = nil;
    【解决方案5】:

    从 iOS 5 和 OS X 10.7 开始,weak 将产生一个自动归零指针。这意味着当指向的对象被释放时,指针会自动设置为nil(详情见Zeroing Weak References in ARC)。

    所以,在 iOS 5+ 和 OS X 10.7+ 下,在 viewDidUnload 方法中手动将 weak IBOutlet 属性设置为 nil 是没有用的:当主视图被卸载时,它的所有子视图将被释放,因此相关属性设置为nil

    【讨论】:

      猜你喜欢
      • 2012-08-19
      • 2011-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-20
      • 2011-07-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多