闭包的强引用循环?

Strong Reference Cycles for Closures?

Swift 闭包在引用 self 时会有很强的引用循环,就像这个例子:

class Test {
  var name = "Hello"

  func doSomething() {
    {() -> Void in 
      self.name = "otherName"
    }()
  }

}

在前面的例子中,我创建了一个强引用循环,所以我必须用以下方法修复它:

class Test {
  var name = "Hello"

  func doSomething() {
    {[unowned self] () -> Void in 
      self.name = "otherName"
    }()
  }

} 

问题:如果我在闭包中引用 self,我必须始终使用 unowned self 还是必须使用 weak self

If I refer self in a closure do I have to use alway unowned self or are there cases where I have to use weak self?

都没有。在大多数情况下,只需正常引用 self 而不对其内存管理进行任何操作。如果存在保留循环的危险,您只需要担心内存管理,除非您将闭包存储在某个地方,例如 self 的 属性,否则不会有这种危险。

您可以通过添加 deinit 实现轻松证明这一点:

class Test {
    var name = "Hello"

    func doSomething() {
        {() -> Void in
            self.name = "otherName"
            }()
    }
    deinit {
        println("bye")
    }
}

现在制作一个测试实例并立即发布:

func testTest () {
    let t = Test()
}

您在控制台中看到"bye",证明实例发布正常。这段代码中从来没有任何类型的 "strong reference cycle" 。你的担心是没有根据的。

[对了,你用错了"closure"这个词。 Every Swift 函数是一个闭包。如果仅因为在闭包中使用单词 self 而存在保留周期问题,则 every Swift 函数将受到此问题的影响 - 显然这是不是这样的。 weakunowned self 发挥作用的地方是在 anonymous 函数中——而且正如我之前所说,如果匿名函数本身也被保留通过 self.]