Search code examples
iosswiftweak-referencesretain-cycleweak

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. dismiss() is an inner function inside setupDismissCallbacks that I'm using to access self values.

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.

How can I verify that the calls inside dismiss won't cause retain cycle?


Solution

  • Just assign your closure to a local variable. At that point, extracting out dismiss is pointless, so just inline it:

    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
    }