Capturing values from context lets a small piece of code remember and use values from around it. This helps keep data handy without passing it again and again.
Capturing values from context in Swift
let closure = { [captureList] in // code using captured values }
The captureList is optional and lets you control how values are captured.
By default, Swift captures values strongly, but you can use weak or unowned to avoid strong references.
x from the surrounding context and prints it.var x = 10 let closure = { print(x) } closure()
x is captured by value at the time of closure creation, so it prints 5 even if x changes later.var x = 5 let closure = { [x] in print(x) } x = 10 closure()
self weakly to avoid strong reference cycles.class Person { var name = "Alice" lazy var greet = { [weak self] in print("Hello, \(self?.name ?? \"Guest\")") } } let p = Person() p.greet()
This program creates a counter closure that captures count by reference. It increments and returns the count each time it is called.
func makeCounter() -> () -> Int { var count = 0 let counter = { count += 1 return count } return counter } let myCounter = makeCounter() print(myCounter()) print(myCounter())
Capturing by value means the closure keeps a copy of the value at the time it is created.
Capturing by reference means the closure uses the current value, which can change later.
Use capture lists to avoid memory problems like strong reference cycles.
Closures can capture values from their surrounding context.
By default, Swift captures variables by reference, but you can capture by value using capture lists.
Capture lists help manage memory and control how values are stored inside closures.
Practice
captures values from context?Solution
Step 1: Understand closure context
A closure can access variables defined outside its own body, in the surrounding scope.Step 2: Capturing means referencing
Capturing means the closure keeps a reference to those external variables so it can use them later.Final Answer:
The closure keeps a reference to variables from its surrounding scope -> Option DQuick Check:
Closure captures = keeps reference [OK]
- Thinking closures create new independent variables
- Believing closures cannot access outside variables
- Confusing capture with copying values
Solution
Step 1: Recognize capture list syntax
To capture by value, Swift uses a capture list with syntax like [var = value].Step 2: Match correct syntax
let closure = { [value = value] in print(value) } uses [value = value] which copies the current value into the closure.Final Answer:
let closure = { [value = value] in print(value) } -> Option BQuick Check:
Capture by copy uses [var = var] syntax [OK]
- Omitting capture list brackets
- Using capture list without assignment
- Writing invalid keywords like 'capture'
var x = 10
let closure = { print(x) }
x = 20
closure()Solution
Step 1: Understand reference capture
The closure capturesxby reference, so it uses the current value when called.Step 2: Check value at call time
Sincexwas changed to 20 before calling the closure, it prints 20.Final Answer:
20 -> Option AQuick Check:
Reference capture prints updated value [OK]
- Assuming closure prints original value 10
- Expecting compilation error due to variable change
- Thinking closure prints nil
var count = 0
let increment = { count += 1 }
increment()
print(count)Solution
Step 1: Check variable mutability
countis a variable (var), so it can be modified inside the closure.Step 2: Verify closure behavior
The closure incrementscountby 1, then printingcountoutputs 1.Final Answer:
No error; code runs and prints 1 -> Option AQuick Check:
Mutable var can be changed inside closure [OK]
- Thinking 'self.' is required outside classes
- Believing inout needed for closure variables
- Assuming closures cannot modify external vars
Solution
Step 1: Understand default capture behavior
By default, closures capture variables by reference, so changes affect the closure.Step 2: Use capture list to copy value
Using a capture list like[value = variable]copies the current value into the closure, isolating it from later changes.Final Answer:
Use a capture list to copy the variable value inside the closure -> Option CQuick Check:
Capture list copies value to freeze it [OK]
- Thinking 'let' alone freezes variable for closure
- Using global variables to avoid capture issues
- Modifying variable inside closure doesn't freeze value
Ready to prove it?
Pass the test and this pattern moves unknown
