MiddleDebuggingCommonNot answered yet
A struct captured in a closure shows the old value after the outer variable changed — explain and fix
The closure below prints 0, not 10, even though counter was mutated before the call. Explain why, and fix it so the latest value is printed.
struct Counter { var value = 0 }
var counter = Counter()
let printLater = { [counter] in print(counter.value) }
counter.value = 10
printLater() // prints 0
Find and fix the bug.
A capture list [value] copies the value type when the closure is created, a snapshot, so later mutations of the outer variable aren't seen. Drop the capture list to capture the variable itself, or use a class to share state.
- ✗Thinking a capture list reads the variable live rather than snapshotting it
- ✗Blaming threading instead of value-copy capture semantics
- ✗Assuming
@escapingchanges what a capture list captures
- →How does capturing without a list differ from a
[counter]list? - →When is snapshotting with a capture list actually the behaviour you want?
The capture list [counter] copies the value type when the closure is created — a snapshot. The later counter.value = 10 changes the outer variable, not the copy inside the closure. Remove the capture list so the closure captures the variable itself:
let printLater = { print(counter.value) } // captures the variable, not a copy
counter.value = 10
printLater() // 10
If you need shared mutable state, make Counter a class.