diff --git a/README.md b/README.md
index e67cedd..cb2cc36 100644
--- a/README.md
+++ b/README.md
@@ -1622,50 +1622,76 @@ _You can enable the following settings in Xcode by running [this script](resourc
-* (link) **Prefer using `weak` captures over `unowned` captures.** [](https://realm.github.io/SwiftLint/unowned_variable_capture.html)
+* (link) **Avoid using `unowned` captures.** Instead prefer safer alternatives like `weak` captures, or capturing variables directly. [](https://realm.github.io/SwiftLint/unowned_variable_capture.html)
- `unowned` captures are unsafe because they will cause the application to crash if the referenced object has been deallocated. `weak` captures are safer because they require the author to explicitly handle the case where the referenced object no longer exists.
+ `unowned` captures are unsafe because they will cause the application to crash if the referenced object has been deallocated.
```swift
- // WRONG: Crashes if `planet` has been deallocated when the closure is called.
-
- spaceship.travel(to: planet, onArrival: { [unowned planet] in
- planet.colonize()
- })
-
- spaceship.travel(to: planet, nextDestination: { [unowned planet] in
- planet.moons.first ?? planet.sun
- })
+ // WRONG: Crashes if `self` has been deallocated when closures are called.
+ final class SpaceshipNavigationService {
+ let spaceship: Spaceship
+ let planet: Planet
+
+ func colonizePlanet() {
+ spaceship.travel(to: planet, onArrival: { [unowned self] in
+ planet.colonize()
+ })
+ }
+
+ func exploreSystem() {
+ spaceship.travel(to: planet, nextDestination: { [unowned self] in
+ planet.moons?.first
+ })
+ }
+ }
```
+
+ `weak` captures are safer because they require the author to explicitly handle the case where the referenced object no longer exists.
```swift
- // RIGHT: Explicitly handles case where `planet` has been deallocated.
-
- spaceship.travel(to: planet, onArrival: { [weak planet] in
- guard let planet else { return }
- planet.colonize()
- })
-
- // For closures that return a non-optional value, you could either
- // use `fatalError` to avoid having to return anything:
- spaceship.travel(to: planet, nextDestination: { [weak planet] in
- guard let planet else {
- fatalError("Planet was unexpectedly deallocated before reached by spaceship")
+ // RIGHT: Uses a `weak self` capture and explicitly
+ // handles the case where `self` has been deallocated
+ final class SpaceshipNavigationService {
+ let spaceship: Spaceship
+ let planet: Planet
+
+ func colonizePlanet() {
+ spaceship.travel(to: planet, onArrival: { [weak self] in
+ guard let self else { return }
+ planet.colonize()
+ })
}
- return planet.moons.first ?? planet.sun
- })
-
- // Or you could return a placeholder value with an optional `assertionFailure`:
- spaceship.travel(to: planet, nextDestination: { [weak planet] in
- guard let planet else {
- assertionFailure("Planet was unexpectedly deallocated before reached by spaceship")
- return Planet()
+ func exploreSystem() {
+ spaceship.travel(to: planet, nextDestination: { [weak self] in
+ guard let self else { return nil }
+ return planet.moons?.first
+ })
+ }
+ }
+ ```
+
+ Alternatively, consider directly capturing the variables that are used in the closure. This lets you avoid having to handle the case where `self` is nil, since you don't even need to reference `self`:
+
+ ```swift
+ // RIGHT: Explicitly captures `planet` instead of capturing `self`
+ final class SpaceshipNavigationService {
+ let spaceship: Spaceship
+ let planet: Planet
+
+ func colonizePlanet() {
+ spaceship.travel(to: planet, onArrival: { [planet] in
+ planet.colonize()
+ })
}
- return planet.moons.first ?? planet.sun
- })
+ func exploreSystem() {
+ spaceship.travel(to: planet, nextDestination: { [planet] in
+ planet.moons?.first
+ })
+ }
+ }
```