首页 > 解决方案 > 闭包递归和保留循环

问题描述

我的关闭保留了自己。它会导致捕获内部的所有其他对象。我可以使用弱引用传递这样的对象,但它并没有解决保留周期的问题。在没有保留循环的情况下使用闭包进行递归的正确方法是什么?

class Foo {
  var s = "Bar"
  deinit {
    print("deinit") // Won't be executed!
  }
}

class TestVC: UIViewController {

  override func viewDidLoad() {
    super.viewDidLoad()

    let foo = Foo() // Weak works, but not the right solution.
    var closure: () -> Void = { return }
    closure = {
      print(foo.s)
      if true {
        return
      } else {
        closure()
      }
    }
  }

}

标签: iosswift

解决方案


您有一个不寻常的设置,您的闭包会自行保留。请注意,Swift 不允许您创建对闭包的弱引用。

要打破保留周期,请在递归的基本情况下设置closure{ }。这是一个测试 macOS 命令行程序:

func test() {
    var closure: ((Int) -> ()) = { _ in }
    closure = { i in
        if i < 10 {
            closure(i + 1)
        } else {
            // Comment out this line for unbounded memory consumption.
            closure = { _ in }
        }
    }
    closure(0)
}

while true {
    test()
}

如果你运行它,它的内存消耗是平稳的。

如果您在基本情况下注释掉 resets 的行closure,它的内存消耗会无限增长。


推荐阅读