【问题标题】:ARC delegate memory managementARC 委托内存管理
【发布时间】:2013-10-03 04:45:07
【问题描述】:

在 Apple 的文档中它说

如果你需要管理资源而不是释放实例变量,你可以实现一个dealloc方法。您不必(实际上您不能)释放实例变量,但您可能需要在系统类和其他未使用 ARC 编译的代码上调用 [systemClassInstance setDelegate:nil]。

这是否包括 UIKit 和框架委托,例如,UIPageViewController 的父级具有委托 UIPageViewControllerDelegate - 这是否必须在 dealloc 中取消?

【问题讨论】:

  • 我假设是的,但从未在 Apple 自己的示例代码中看到过。
  • 您所说的“父母...有代表”是什么意思。在这种情况下,哪些类的 dealloc 实现将设置为 nil?
  • @CarlVeazey Parent 是一个 UIViewContoller,它采用 UIPageViewControllerDelegate 协议,带有一个 UIPageViewControlle 的实例。

标签: ios objective-c memory-management delegates automatic-ref-counting


【解决方案1】:

当父控制器与其视图之间存在关系时,父控制器充当视图代理,其中一个关系不能保留另一个,否则您将有一个保留周期和内存泄漏。

有两种方法可以做到这一点:

  • 首先要将委托标记为 __unsafe_unretained。如果您这样做,您将需要手动清除控制器的 dealloc 中的引用。

  • 二是使用弱引用。大多数 ARC 发生在编译时。这有助于通过减少垃圾收集器可能发生的 CPU 周期来节省电池消耗。然而,对于弱引用,有一个运行时进程维护这些变量的映射,观察它们,并根据需要将它们消除。这就是为什么弱引用需要 iOS5.1 - 它不仅仅是一个编译器功能。

  • 如果使用过多的弱引用,可能会造成性能开销。在实践中,这几乎不会成为一个问题。

总结

  • 不,如果您使用弱引用,则不需要手动将其清除。通过强引用的保留循环检查您是否没有记忆。
  • 仅在确实需要时才使用 __unsafe_unretained(又名“assign”)。
  • 同样的规则适用于 UIKit 和框架类。好消息是它们非常一致。

更新

  • 更正我的狡猾评论:如果您的委托控制器离开之前离开,那么您将需要手动将其从控制器中清除 - 感谢@borrden。

【讨论】:

  • 所以在我的示例中,分配了 UIPageViewControllerDelegate,这会在 dealloc 中被取消吗?
  • 查看文档,这个属性已经是“分配”范围的。 (旧式的弱)。因此,Apple 会为您处理好它。 developer.apple.com/library/ios/documentation/uikit/reference/… 。 .所以这意味着你没有。
  • 危险地不正确(或至少措辞奇怪)。 assign 不是“旧式weak”,它与unsafe-unretained 相同。请参阅第 4.1.1 节clang.llvm.org/docs/AutomaticReferenceCounting.html
  • 如果您设置了一个不安全的未保留委托,您需要将其设为 nil,如您所述。您的评论似乎与您在回答中所说的相矛盾。
  • @daidai - 请注意,borrden 是正确的。如果您的委托在控制器之前消失了,那么您需要将其从控制器中清除。
猜你喜欢
  • 2013-01-17
  • 1970-01-01
  • 2011-11-14
  • 2013-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-27
相关资源
最近更新 更多