这会导致Swift保留周期吗?

时间:2018-03-28 01:19:34

标签: swift closures

我有这个代码,我在质疑是否需要使用捕获列表来引用self弱的引用。

现在我认为getTextFileData.main.async是静态方法,因此,这不会导致保留周期。但是,我确实访问games属性,有点不确定。

    NPWebService.getTextFileData { (games, success) in
        if success {
            self.games = games
            DispatchQueue.main.async {
                self.updateUI()
            }
        }
    }

1 个答案:

答案 0 :(得分:5)

这不会导致保留循环,因为它看起来像是不同类型的静态方法。因此getTextFileData方法将暂时保留您传入的闭包,直到任何异步工作完成,并且闭包将暂时保留self。但是当工作完成并且关闭完成后,这些临时保留将到期,并且自动内存管理可以适当地清理。

保留周期的危险在于你有一个引用/捕获self的闭包,而self也会保留闭包。像这样:

class GameController {
  var games: [Game]?
  // self retains the closure as a property
  let updateClosure:([Game], Bool)->() = {
    games, success in
    if success {
      self.games = games // and the closure captures self. Each retains each other indefinitely, this is a retain cycle and neither this closure nor self will ever be deallocated 
    }
  }

  func load() {
    NPWebService.getTextFileData(updateClosure)
  }
}

通常只需要关闭捕获列表中的弱自我或无主自我:

  • 如果self或self保留的东西将保留该闭包(当在调用站点本地和瞬时创建闭包以作为参数传递给方法时,很少会出现这种情况)
  • 如果出于非保留周期的原因,所需的行为是允许在完成某些异步工作之前以及在调用闭包之前释放self。在这种情况下,闭包不应强烈捕获自我,而应该弱调整它,并在调用闭包时使用self之前检查它是否仍然存在