Rule Swift

Weak Self in Closures

Use [weak self] in closures that outlive the current scope

swiftmemoryclosuresmacosios
CLAUDE.md

Use [weak self] in all closures that capture self and outlive the call — callbacks, animation completions, async dispatches, notification observers. Follow with guard let self else { return } or optional chaining.

// Good
DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in
    guard let self else { return }
    self.updateUI()
}

// Bad — retains self until the closure completes
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
    self.updateUI()
}

Synchronous closures like map, filter, reduce do not need [weak self] because they execute immediately and don’t outlive the call.

Copy this block into your CLAUDE.md or agent config file to enforce it in your workflow.

get crystl