You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+59-33Lines changed: 59 additions & 33 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1622,50 +1622,76 @@ _You can enable the following settings in Xcode by running [this script](resourc
1622
1622
1623
1623
</details>
1624
1624
1625
-
*<a id='unowned-captures'></a>(<a href='#unowned-captures'>link</a>) **Prefer using `weak` captures over `unowned` captures.** [](https://realm.github.io/SwiftLint/unowned_variable_capture.html)
1625
+
*<a id='unowned-captures'></a>(<a href='#unowned-captures'>link</a>) **Avoid using `unowned` captures.** Instead prefer safer alternatives like `weak` captures, or capturing variables directly. [](https://realm.github.io/SwiftLint/unowned_variable_capture.html)
1626
1626
1627
1627
<details>
1628
-
`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 casewhere the referenced object no longer exists.
1628
+
`unowned` captures are unsafe because they will cause the application to crash if the referenced object has been deallocated.
1629
1629
1630
1630
```swift
1631
-
// WRONG: Crashes if `planet` has been deallocated when the closure is called.
1632
-
1633
-
spaceship.travel(to: planet, onArrival: { [unowned planet] in
1634
-
planet.colonize()
1635
-
})
1636
-
1637
-
spaceship.travel(to: planet, nextDestination: { [unowned planet] in
1638
-
planet.moons.first?? planet.sun
1639
-
})
1631
+
// WRONG: Crashes if `self` has been deallocated when closures are called.
1632
+
finalclass SpaceshipNavigationService {
1633
+
let spaceship: Spaceship
1634
+
let planet: Planet
1635
+
1636
+
funccolonizePlanet() {
1637
+
spaceship.travel(to: planet, onArrival: { [unownedself] in
1638
+
planet.colonize()
1639
+
})
1640
+
}
1641
+
1642
+
funcexploreSystem() {
1643
+
spaceship.travel(to: planet, nextDestination: { [unownedself] in
1644
+
planet.moons?.first
1645
+
})
1646
+
}
1647
+
}
1640
1648
```
1649
+
1650
+
`weak` captures are safer because they require the author to explicitly handle the casewhere the referenced object no longer exists.
1641
1651
1642
1652
```swift
1643
-
// RIGHT: Explicitly handles case where `planet` has been deallocated.
1644
-
1645
-
spaceship.travel(to: planet, onArrival: { [weak planet] in
1646
-
guardlet planet else { return }
1647
-
planet.colonize()
1648
-
})
1649
-
1650
-
// For closures that return a non-optional value, you could either
1651
-
// use `fatalError` to avoid having to return anything:
1652
-
spaceship.travel(to: planet, nextDestination: { [weak planet] in
1653
-
guardlet planet else {
1654
-
fatalError("Planet was unexpectedly deallocated before reached by spaceship")
1653
+
// RIGHT: Uses a `weak self` capture and explicitly
1654
+
// handles the case where `self` has been deallocated
1655
+
finalclassSpaceshipNavigationService {
1656
+
let spaceship: Spaceship
1657
+
let planet: Planet
1658
+
1659
+
funccolonizePlanet() {
1660
+
spaceship.travel(to: planet, onArrival: { [weakself] in
1661
+
guardletselfelse { return }
1662
+
planet.colonize()
1663
+
})
1655
1664
}
1656
1665
1657
-
return planet.moons.first?? planet.sun
1658
-
})
1659
-
1660
-
// Or you could return a placeholder value with an optional `assertionFailure`:
1661
-
spaceship.travel(to: planet, nextDestination: { [weak planet] in
1662
-
guardlet planet else {
1663
-
assertionFailure("Planet was unexpectedly deallocated before reached by spaceship")
1664
-
returnPlanet()
1666
+
funcexploreSystem() {
1667
+
spaceship.travel(to: planet, nextDestination: { [weakself] in
1668
+
guardletselfelse { returnnil }
1669
+
return planet.moons?.first
1670
+
})
1671
+
}
1672
+
}
1673
+
```
1674
+
1675
+
Alternatively, consider directly capturing the variables that are used in the closure. This lets you avoid having to handle the casewhere `self` isnil, since you don't even need to reference `self`:
1676
+
1677
+
```swift
1678
+
// RIGHT: Explicitly captures `planet` instead of capturing `self`
1679
+
finalclassSpaceshipNavigationService {
1680
+
let spaceship: Spaceship
1681
+
let planet: Planet
1682
+
1683
+
funccolonizePlanet() {
1684
+
spaceship.travel(to: planet, onArrival: { [planet] in
1685
+
planet.colonize()
1686
+
})
1665
1687
}
1666
1688
1667
-
return planet.moons.first?? planet.sun
1668
-
})
1689
+
funcexploreSystem() {
1690
+
spaceship.travel(to: planet, nextDestination: { [planet] in
0 commit comments