Swift 5.8 supports implicit self for weak self captures

·

2 min read

I greatly enjoyed reading the notes of Swift 5.8 over my morning coffee. I found many of the new features difficult to understand, but one feature in particular I was delighted to see. After learning how to manage retain cycles and prevent memory leaks, I've been wondering why we need all the visual noise when we capture weak self but not self. When reading the proposal, I found that using implicit self in a closure was fixed in Swift 5.3 thanks to this proposal.

And now in Swift 5.8, as long as we safely unwrap self, we can use implicit self when weak self is captured! Thanks to this proposal.

Here are the examples from the proposal on GitHub, all the sources are linked at the bottom of this article:

Before 5.8

button.tapHandler = { [weak self] in
    guard let self else { return }
    self.dismiss()
}

After 5.8

  button.tapHandler = { [weak self] in
            guard let self else { return }
            dismiss()
        }

So what about nested closures?

Additonal closures nested inside the [weak self] closure must first capture self explicitly to use implicit self.

// Not allowed:
couldCauseRetainCycle { [weak self] in
  guard let self else { return }
  foo()

  couldCauseRetainCycle {
    // error: call to method 'method' in closure requires 
    // explicit use of 'self' to make capture semantics explicit
    bar()
  }
}

// Allowed:
couldCauseRetainCycle { [weak self] in
  guard let self else { return }
  foo()

  couldCauseRetainCycle { [weak self] in
    guard let self else { return }
    bar()
  }
}

// Also allowed:
couldCauseRetainCycle { [weak self] in
  guard let self else { return }
  foo()

  couldCauseRetainCycle {
    self.bar()
  }
}

// Also allowed:
couldCauseRetainCycle { [weak self] in
  guard let self else { return }
  foo()

  couldCauseRetainCycle { [self] in
    bar()
  }
}

This is great news, as this will reduce unnecessary clutter, noise and repetitiveness.

Sources:

https://github.com/apple/swift-evolution/blob/main/proposals/0269-implicit-self-explicit-capture.md

https://github.com/apple/swift-evolution/blob/main/proposals/0365-implicit-self-weak-capture.md