A capture list is a way to define how variables are captured inside a closure. It lets you specify whether to capture variables strongly, weakly, or unowned to control memory management and avoid retain cycles.
Click to reveal answer
beginner
Why do we use capture lists in closures?
We use capture lists to avoid strong reference cycles (retain cycles) by controlling how variables are captured. For example, capturing a variable as weak or unowned prevents the closure from keeping the variable alive forever.
Click to reveal answer
beginner
How do you write a capture list in a Swift closure?
You write a capture list inside square brackets before the closure parameters. For example: {[weak self] in ...} captures self weakly inside the closure.
Click to reveal answer
intermediate
What is the difference between capturing a variable as weak and unowned in a capture list?
Capturing as weak means the variable can become nil and is optional inside the closure. Capturing as unowned means the variable is expected to always exist and is non-optional, but if it doesn't exist, the program will crash.
Click to reveal answer
intermediate
Show an example of a capture list preventing a retain cycle with self in a closure.
Example:
class MyClass {
var closure: (() -> Void)?
func setup() {
closure = { [weak self] in
print(self)
}
}
}
Here, self is captured weakly to avoid a retain cycle between the class and the closure.
Click to reveal answer
What does the capture list [weak self] do inside a Swift closure?
APrevents the closure from running
BCaptures self strongly to keep it alive
CMakes self optional outside the closure
DCaptures self weakly to avoid retain cycles
✗ Incorrect
The capture list [weak self] captures self weakly inside the closure to avoid strong reference cycles.
Where do you place the capture list in a Swift closure?
AAt the end of the function
BInside square brackets before the closure parameters
CInside the closure body
DAfter the closure body
✗ Incorrect
Capture lists are placed inside square brackets before the closure parameters.
What happens if you capture a variable as unowned but it becomes nil?
AThe program crashes
BThe variable becomes optional
CThe closure ignores the variable
DThe variable is captured weakly instead
✗ Incorrect
Capturing as unowned assumes the variable always exists; if it becomes nil, the program crashes.
Why might you want to use a capture list in a closure?
ATo control how variables are captured and avoid memory leaks
BTo make the closure run faster
CTo change the closure's return type
DTo make the closure synchronous
✗ Incorrect
Capture lists help control variable capture to avoid retain cycles and memory leaks.
Which of these is a correct capture list syntax?
A{ weak self in print(self) }
B{ (weak self) -> Void in print(self) }
C{ [weak self] in print(self) }
D{ [self weak] in print(self) }
✗ Incorrect
The correct syntax uses square brackets: { [weak self] in ... }
Explain what a capture list is and why it is important in Swift closures.
Think about how closures keep references to variables and how that can cause problems.
You got /4 concepts.
Describe the difference between capturing a variable as weak versus unowned in a closure's capture list.
Consider safety and lifetime guarantees of the captured variable.
You got /4 concepts.
Practice
(1/5)
1. What is the main purpose of using a capture list in a Swift closure?
easy
A. To control how variables are stored and referenced inside the closure
B. To define the return type of the closure
C. To specify the closure's parameter types
D. To make the closure run asynchronously
Solution
Step 1: Understand what capture lists do
Capture lists let you specify how variables are captured inside closures, either by strong, weak, or unowned references.
Step 2: Identify the main purpose
The main purpose is to control how variables are stored and referenced to avoid memory leaks or unexpected behavior.
Final Answer:
To control how variables are stored and referenced inside the closure -> Option A
Quick Check:
Capture list purpose = control variable capture [OK]
2. Which of the following is the correct syntax to declare a capture list with a weak reference to self in a Swift closure?
easy
A. let closure = { [self weak] in print(self) }
B. let closure = { weak self in print(self) }
C. let closure = { [weak self] in print(self) }
D. let closure = { (weak self) in print(self) }
Solution
Step 1: Recall capture list syntax
Capture lists are declared inside square brackets before the closure parameters, e.g., [weak self].
Step 2: Match correct syntax
let closure = { [weak self] in print(self) } uses the correct syntax: [weak self] inside square brackets before the closure body.
Final Answer:
let closure = { [weak self] in print(self) } -> Option C
Quick Check:
Capture list syntax = [weak self] [OK]
Hint: Capture lists go inside square brackets before closure body [OK]
Common Mistakes:
Omitting square brackets around capture list
Placing 'weak' outside the brackets
Using parentheses instead of brackets
3. What will be the output of the following Swift code?
class Example {
var value = 10
lazy var closure: () -> Void = { [unowned self] in
print(self.value)
}
}
let example = Example()
example.value = 20
example.closure()
medium
A. 20
B. 10
C. Runtime error
D. nil
Solution
Step 1: Understand unowned self capture
The closure captures self as unowned, meaning it references the original object without increasing retain count.
Step 2: Check value at closure call
example.value is updated to 20 before calling closure, so print(self.value) outputs 20.
Final Answer:
20 -> Option A
Quick Check:
Unowned self captures current value = 20 [OK]
Hint: Unowned self captures current object state, not copy [OK]
Common Mistakes:
Thinking closure captures old value copy
Confusing unowned with weak causing nil
Expecting runtime error without object deallocation
4. Identify the error in this Swift closure using a capture list:
class Test {
var count = 0
lazy var closure: () -> Void = { [weak self] in
self.count += 1
print(self.count)
}
}
medium
A. No error, code is correct
B. Capture list syntax is incorrect
C. Closure cannot be lazy with capture list
D. Cannot use weak self without unwrapping optional
Solution
Step 1: Analyze weak self usage
When capturing self as weak, self becomes an optional inside the closure.
Step 2: Check code for optional unwrapping
The code uses self.count directly without unwrapping, causing a compile error.
Final Answer:
Cannot use weak self without unwrapping optional -> Option D
Quick Check:
Weak self requires optional unwrapping [OK]
Hint: Weak self is optional; unwrap before use [OK]
Common Mistakes:
Using weak self as non-optional
Ignoring optional chaining or guard let
Assuming lazy closures can't have capture lists
5. You want to create a closure that captures a variable by making a copy of it, so changes outside the closure don't affect the closure's value. Which capture list syntax should you use in Swift?
hard
A. [weak variable]
B. [value = variable]
C. [unowned variable]
D. [copy variable]
Solution
Step 1: Understand capture by copy
To capture a variable by making a copy, you assign it inside the capture list using syntax like [value = variable].
Step 2: Evaluate options
[value = variable] uses the correct syntax to copy the variable's value into the closure's capture list.
Final Answer:
[value = variable] -> Option B
Quick Check:
Copy capture syntax = [value = variable] [OK]
Hint: Use [newName = oldVar] to capture a copy [OK]
Common Mistakes:
Using weak or unowned which capture references
Assuming [copy variable] is valid syntax
Not assigning variable inside capture list
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.