Weak Self In Escaping Closures
Strong captures inside an `@escaping` closure that the receiver itself stores — completion blocks, Combine subscribers, NotificationCenter observers, async tasks held on a controller, timer handlers — create a retain cyc…
$ prime install @ios-swift/rule-weak-self-in-escaping-closures Projection
Always in _index.xml · the agent never has to ask for this.
WeakSelfInEscapingClosures [rule] v0.1.0
Strong captures inside an @escaping closure that the receiver itself stores — completion blocks, Combine subscribers, NotificationCenter observers, async tasks held on a controller, timer handlers — create a retain cycle. The receiver retains the closure, the closure retains the receiver, neither deinits. The fix is [weak self] in the capture list, paired with a guard let self else { return } (or optional-chained self?.) inside the body.
Loaded when retrieval picks the atom as adjacent / supporting.
WeakSelfInEscapingClosures [rule] v0.1.0
Strong captures inside an @escaping closure that the receiver itself stores — completion blocks, Combine subscribers, NotificationCenter observers, async tasks held on a controller, timer handlers — create a retain cycle. The receiver retains the closure, the closure retains the receiver, neither deinits. The fix is [weak self] in the capture list, paired with a guard let self else { return } (or optional-chained self?.) inside the body.
Checks
- Every
@escapingclosure that is stored onself(or on an object that outlivesself) capturesselfwith[weak self]. - After the capture, the body either uses
self?.xor unwraps once at the top withguard let self else { return }. - Timer, NotificationCenter, KVO, and Combine subscriptions stored on a view controller use
[weak self]in their handler closures. - Non-escaping closures (e.g. the closure passed to
array.map,forEach, syncwithLock) do not need[weak self]— strong is fine because the closure does not outlive the call. - When
[weak self]would force the closure to do nothing useful ifselfis gone, but the work must still complete, capture[weak self]plus a strong copy of the specific dependency the closure actually needs.
Label
Capture self weakly in any escaping closure stored on self or owned by a longer-lived object
Loaded when retrieval picks the atom as a focal / direct hit.
WeakSelfInEscapingClosures [rule] v0.1.0
Strong captures inside an @escaping closure that the receiver itself stores — completion blocks, Combine subscribers, NotificationCenter observers, async tasks held on a controller, timer handlers — create a retain cycle. The receiver retains the closure, the closure retains the receiver, neither deinits. The fix is [weak self] in the capture list, paired with a guard let self else { return } (or optional-chained self?.) inside the body.
Checks
- Every
@escapingclosure that is stored onself(or on an object that outlivesself) capturesselfwith[weak self]. - After the capture, the body either uses
self?.xor unwraps once at the top withguard let self else { return }. - Timer, NotificationCenter, KVO, and Combine subscriptions stored on a view controller use
[weak self]in their handler closures. - Non-escaping closures (e.g. the closure passed to
array.map,forEach, syncwithLock) do not need[weak self]— strong is fine because the closure does not outlive the call. - When
[weak self]would force the closure to do nothing useful ifselfis gone, but the work must still complete, capture[weak self]plus a strong copy of the specific dependency the closure actually needs.
Label
Capture self weakly in any escaping closure stored on self or owned by a longer-lived object
Label
Capture self weakly in any escaping closure stored on self or owned by a longer-lived object
Source
prime-system/examples/ios-swift/primes/compiled/@ios-swift/rule-weak-self-in-escaping-closures/atom.yaml