Unnecessary self weak dance

I saw this pattern which in a distilled form is equivalent to:

struct S {
    init(closure: () -> Void) {}
}

class C {
    func foo() -> S {
        S { [weak self] in 
            guard let self else { return }
            // do something
        }
    }
}

It doesn't make sense to me as the closure is non escaping so no way self could be gone. Or is there a legitimate usefulness to this pattern?

If it's useless, should't Swift put a warning about unnecessary weak capture?

1 Like

It doesn’t make sense to do so from the code execution perspective, however from the project perspective “always use weak captures in closures“ can be a useful generalization :man_tipping_hand:

  • It’s better to have redundant weak captures than memory leaks
  • It’s better to have thoughtfully written code than redundant weak captures
  • Maybe for some folks thoughtfully written code is not an option and it’s fine :sweat_smile:

It makes no sense, but a large number of Swift developers are under the mistaken impression that [weak self] is a reasonable default, and some even (regrettably, imho) require it using linters or other tooling.

2 Likes

The closure still holds a strong reference to self during execution because of the guard statement. So I think the explicit weak capture is ambiguous and confusing.
EDIT: on a second thought this isn't a valid reason because it's true in those scenarios that requires weak capture too.