Introduction
By default, closures passed as function parameters in Swift are non-escaping, meaning they must be called before the function they were passed to returns, for memory-safety and performance reasons. Some scenarios, such as storing a closure for later or invoking it asynchronously in a completion handler, require the closure to outlive the function call. Swift's @escaping attribute marks such parameters explicitly. A related but different feature, @autoclosure, automatically wraps an expression passed as an argument into a closure, deferring its evaluation until the closure is actually called.
Cricket analogy: A commentator's live remark closure is non-escaping, spoken and gone before the over ends, but a post-match analysis closure marked @escaping is stored to replay after the game finishes; @autoclosure is like a pundit's prepared one-liner only spoken if the moment actually calls for it.
Syntax
func performLater(action: @escaping () -> Void) {
// action may be stored and called after this function returns
}
func logIfTrue(_ condition: @autoclosure () -> Bool) {
if condition() {
print("true")
}
}Explanation
A non-escaping closure is guaranteed to be called synchronously and discarded once the function returns, so Swift can optimize memory management around it. When you need to store a closure in a property, add it to an array, or call it later inside an asynchronous callback (such as a network request completion handler), you must mark the parameter @escaping, telling the compiler and readers that the closure's lifetime can extend beyond the function call. @autoclosure, by contrast, is about deferring evaluation: it lets a caller write a plain expression instead of an explicit closure, and Swift automatically wraps that expression in a closure so it is only evaluated when the parameter is actually used inside the function. This is how functions like assert(_:_:) and the ?? nil-coalescing operator avoid evaluating their second argument unless it is actually needed.
Cricket analogy: A ball-by-ball reaction closure is guaranteed synchronous and discarded once the over finishes, but a closure stored in an array of 'moments to replay after the match' must be marked @escaping since it outlives the live over; the ?? nil-coalescing default score behaves like @autoclosure, only computed if the actual score is missing.
Example
var savedCompletion: (() -> Void)?
func fetchData(completion: @escaping () -> Void) {
savedCompletion = completion // stored for later, after fetchData returns
}
func logIfTrue(_ condition: @autoclosure () -> Bool) {
if condition() {
print("Condition was true")
}
}
fetchData {
print("Data fetched!")
}
savedCompletion?()
logIfTrue(5 > 3)Output
Data fetched!
Condition was trueKey Takeaways
- Closures are non-escaping by default; they must be called before the function they were passed to returns.
@escapingmarks a closure parameter that may be stored or called after the function returns, such as in async callbacks.@autoclosureautomatically wraps a plain expression argument into a closure, deferring its evaluation.@autoclosureis used by functions likeassertand operators like??to avoid unnecessary evaluation.- Escaping closures often need to capture
selfor other references explicitly, which is important for memory management.
Practice what you learned
1. What is the default behavior of a closure passed as a function parameter in Swift?
2. When must you mark a closure parameter with @escaping?
3. What does @autoclosure do?
4. Which of these commonly uses autoclosures?
5. Why are closures non-escaping by default in Swift?
Was this page helpful?
You May Also Like
Closures in Swift
Understand closures as self-contained blocks of functionality that capture and store references to surrounding variables.
Higher-Order Functions in Swift
Explore functions that take other functions or closures as arguments, such as map, filter, and reduce.
Nil Coalescing Operator in Swift
The `??` operator supplies a default value when an optional is nil, in a single concise expression.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics