Escaping Closures
An escaping closure is one that's saved to be used later, after the function that created it has already finished and gone away.
Declaring an Escaping Closure Parameter
Marking a closure parameter @escaping allows it to be stored (for example, in an array) and invoked later, even after the function that received it has already returned.
Example: Declaring an Escaping Closure Parameter
var savedCompletions: [() -> Void] = []
func saveCompletion(_ completion: @escaping () -> Void) {
savedCompletions.append(completion)
}
saveCompletion { print("Completion 1 ran") }
saveCompletion { print("Completion 2 ran") }
for completion in savedCompletions {
completion()
}
Login to try C/C++/Java/PHP code in the editor
Non-Escaping by Default
Closures are non-escaping by default, meaning they must be called before the function returns -- this is more memory-efficient and is what makes something like .map's closure argument safe without @escaping.
Example: Non-Escaping by Default
func runImmediately(_ action: () -> Void) {
print("About to run")
action()
print("Finished running")
}
runImmediately {
print("Running the action now")
}
Login to try C/C++/Java/PHP code in the editor
Common Mistakes
- Forgetting to mark a closure parameter
@escapingwhen it's stored in a property or called after the function returns -- the compiler will flag this. - Assuming all closures need
@escaping; a closure only needs it if it outlives the function call, e.g. stored for later or used asynchronously. - Creating a strong reference cycle by capturing
selfstrongly inside a stored escaping closure without using[weak self].
Chapter Summary
- A closure parameter must be marked
@escapingif it's stored or called after the function returns. - Non-escaping closures (the default) must be used only during the function call itself.
- Escaping closures are common for completion handlers and asynchronous callbacks.
- Capturing
selfin a stored escaping closure risks a retain cycle unless handled carefully.
🔒
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: