简体   繁体   English

内部功能保留周期

[英]Function inside Function retain cycle

I was wondering how to avoid retain cycle in the following scenario: 我想知道在以下情况下如何避免保留周期:

private func setupDismissCallbacks() {

  // inner func     
  func dismiss() {
     self.videoExporter?.cancel()
     self.rootViewController.dismiss(animated: true, completion: nil)
     self.delegate?.childCoordinatorDidFinish(self)
  }

  // first clousre       
  saveModalViewController.onButtonDismiss = {  [weak self] in
     // not really using `self` here
     guard let self = self else { return }
     dismiss()
  }

  // second clousre  
  saveModalViewController.onDimmedAreaDismiss = { [weak self] in
     // not really using `self` here
     guard let self = self else { return }
     dismiss()
  }

}

I have a function setupDismissCallbacks that listens to two callbacks from a saveModalViewController self property. 我有一个函数setupDismissCallbacks ,它侦听来自saveModalViewController自身属性的两个回调。 dismiss() is an inner function inside setupDismissCallbacks that I'm using to access self values. dismiss()setupDismissCallbacks内部的一个内部函数,用于访问self值。

But inside the closures onButtonDismiss and onDimmedAreaDismiss I don't access self to call dismiss , and I can't add [weak self] into dismiss function because it's a function. 但是在闭包中的onButtonDismissonDimmedAreaDismiss我无法访问self来调用dismiss ,并且我无法将[weak self]添加到dismiss函数中,因为它是一个函数。

How can I verify that the calls inside dismiss won't cause retain cycle? 我如何可以验证电话里dismiss不会造成保留周期?

Just assign your closure to a local variable. 只需将闭包分配给局部变量即可。 At that point, extracting out dismiss is pointless, so just inline it: 那时, dismiss是没有意义的,因此只需内联即可:

private func setupDismissCallbacks() {     
    let dismissCallback: () -> Void = {  [weak self] in
        guard let self = self else { return }
        self.videoExporter?.cancel()
        self.rootViewController.dismiss(animated: true, completion: nil)
        self.delegate?.childCoordinatorDidFinish(self)
    }

    saveModalViewController.onButtonDismiss = dismissCallback
    saveModalViewController.onDimmedAreaDismiss = dismissCallback
}

@Alexander explained the issue in the comments: @Alexander在评论中解释了这个问题:

Your inner function captures self . 你的内在功能可以捕捉self Your two closures capture that inner function (including the context it encloses over, which includes self ). 您的两个闭包捕获了该内部函数(包括其所包围的上下文,其中包括self )。 Since your two closures are strongly referenced by saveModalViewController (which I assume is strongly referenced by self ), you have a retain cycle. 由于您的两个闭包均由saveModalViewController强烈引用(我假设由self强烈引用),因此您有一个保留周期。

You can break this cycle by not having dismiss capture self . 您可以通过不dismiss捕获self来打破此循环。 Pass the SaveCoordinator to dismiss : 通过SaveCoordinator dismiss

private func setupDismissCallbacks() {     
  func dismiss(_ coordinator: SaveCoordinator) {
     coordinator.videoExporter?.cancel()
     coordinator(animated: true, completion: nil)
     coordinator.delegate?.childCoordinatorDidFinish(coordinator)
  }

  // first clousre       
  saveModalViewController.onButtonDismiss = {  [weak self] in
     guard let self = self else { return }
     dismiss(self)
  }

  // second clousre  
  saveModalViewController.onDimmedAreaDismiss = { [weak self] in
     guard let self = self else { return }
     dismiss(self)
  }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM