What does a capture list like [weak self], [unowned self], [self], or [foo] actually do?

1.5.4 · L2 · Interview

Reported at: PhonePe

Mental model. A capture list is a photocopier at the moment the closure is created. Whatever is on the glass gets copied; later edits to the original do not appear.

A capture list decides how and when names are captured, at closure creation time:

  • [weak self] — self becomes an optional weak reference; no retain, no cycle.
  • [unowned self] — non-optional, no retain, crashes if self is gone.
  • [self] on a class — same as capturing self strongly; mostly a Swift 5.3+ way to say “yes, I meant self” without self. noise.
  • [foo] on a struct — a copy of the value, not a reference to the variable.

Without a list, a closure captures the variable (the storage), so it reads later mutations.

Common traps

  • “[self] makes a copy of the object.” For a class it copies the reference. Only value types get a value snapshot.
  • “[weak self] is always the safe choice.” If the closure must complete (a save operation), a weakly-captured self may vanish and the work silently never finishes. Sometimes strong capture is correct.

They might follow up with

  • What is the difference between [weak self] and [unowned self]? Both avoid a retain; weak nils out, unowned traps. Use unowned only when the owner provably outlives the closure.
  • Does a capture list copy a class instance? No — it copies the reference, plus changes the ownership qualifier.

Related questions

  • 1.5.5 Why does this print the new city without a capture list, and the old one with [city]?
  • 1.5.3 Why are closures called reference types? What is a closure context?
  • 1.5.6 unowned var view = UIView() then print(view) — what happens?

← Why are closures called reference types? What is a closure context?   Why does this print the new city without a capture list, and the old… →