【问题标题】:Does holding a weak reference prevent a retain cycle from being considered a leak?持有弱引用是否可以防止保留周期被视为泄漏?
【发布时间】:2018-07-02 19:35:51
【问题描述】:

考虑以下代码。我创建了 2 个 Foo 对象,并为每个对象提供了对另一个对象的强引用:

class Foo: {
  var otherFoo: Foo?
  var value: Int
}

class FooContainer {

  weak var aFoo: Foo?

  var firstFoo = Foo(otherFoo: nil, value: 1)
  var secondFoo = Foo(otherFoo: firstFoo, value: 2)
  firstFoo.otherFoo = secondFoo //The 2 foo objects now form a retain cycle
  aFoo = firstFoo //save a weak reference to one of the Foo objects    
}

上面肯定是一个retain循环,但它是内存泄漏吗?我将对其中一个对象的弱引用保存到实例变量中。

Instruments Leaks 工具和 Xcode 的内存图实用程序都没有将上述情况标记为泄漏。如果您删除对 aFoo 的分配,则 2 个 Foo 对象标记为泄漏。

保留循环是否仅在没有外部引用时才被视为泄漏?

【问题讨论】:

  • 对不起,你们都说得对。那应该是class Foo,而不是struct foo。我没有想。关闭以纠正我的问题。
  • 循环对象图还不错。它们非常有用,例如用于建模图算法。由执行不善的循环对象图引起的泄漏是不好的。由于实施不善,我会导致 strong 保留周期
  • 再循环对象图,我理解它们的用处。双链表就是一个简单的例子。 Cocoa 中通常的约定是指定“向前”和“向后”方向,并使向后指向的链接变弱。否则,如果您有周期性强引用,则必须真正小心处理。
  • 我希望 Xcode/Instruments 将一对强链接对象视为内存泄漏,除非还有一个 strong 引用将它们“锚定”到您的对象的其他位置图表。
  • 然后呢?不是这样吗?

标签: swift memory-leaks


【解决方案1】:

保留循环是对象的“循环”,每个对象都持有一个强引用 到下一个,这样它们都不能被释放。

leak 分配了不可“访问”的内存,即没有 指向它的指针。

在您的情况下,两个 Foo 实例构建了一个保留周期,但它是 不是泄漏(只要存在 FooContainer 实例) 因为可以通过aFoo 访问这些实例 属性。

aFoo 是一个弱属性在这里无关紧要:firstFoo 实例永远不会被释放(作为保留周期的一部分),因此 弱引用永远不会无效。

【讨论】:

  • 我经常听到被称为“废弃”或“孤立”的非泄漏丢失内存。保留周期只是其中一种情况。
  • 我们应该区分retain cyclestrong retain cycle吗?即使它具有不会导致strong retain cycle 的弱引用,它是否仍称为retain cycle
  • 我只听说过“保留周期”用于引用两个通过强引用保持彼此存活的对象。
  • 澄清点:不只是两个对象。您可以拥有各种拓扑的 n 路保留循环。例如,超立方体。
猜你喜欢
  • 2020-03-22
  • 1970-01-01
  • 1970-01-01
  • 2012-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-09
相关资源
最近更新 更多