Capturing values from context in Swift - Time & Space Complexity
When we capture values from context in Swift, we often use closures that remember variables from outside their own code. Understanding how this affects the time it takes to run is important.
We want to see how the program's work grows as the input or captured data changes.
Analyze the time complexity of the following code snippet.
func makeIncrementer(amount: Int) -> () -> Int {
var total = 0
return {
total += amount
return total
}
}
let incrementByTen = makeIncrementer(amount: 10)
for _ in 1...5 {
print(incrementByTen())
}
This code creates a closure that captures a variable from its surrounding context and updates it each time the closure runs.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The closure increments and returns the captured variable
total. - How many times: The closure runs 5 times in the loop.
Each time the closure runs, it does a simple addition and returns a value. The work grows directly with how many times we call the closure.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 additions and returns |
| 100 | 100 additions and returns |
| 1000 | 1000 additions and returns |
Pattern observation: The number of operations grows in a straight line with the number of times the closure is called.
Time Complexity: O(n)
This means the time to run grows directly with how many times the closure is executed.
[X] Wrong: "Capturing a variable inside a closure makes the code run slower each time because it copies all data every call."
[OK] Correct: The closure only keeps a reference to the variable, so each call just updates that one value, not copying all data repeatedly.
Understanding how closures capture and use variables helps you explain how your code manages memory and speed. This skill shows you can think about how code runs, not just what it does.
What if the closure captured a large array and modified it each time? How would the time complexity change?
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
