Escaping Closures
Store closures that outlive their function.
Escaping Closures is a free Swift Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Swift Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Escaping vs Non-Escaping
By default a closure parameter is non-escaping: it must be called before the function returns. Mark it @escaping if it may be stored and called later.
A Non-Escaping Closure
This closure runs synchronously and is gone when the function returns:
func run(_ work: () -> Void) {
work()
}
run { print("done now") } // "done now"Why @escaping Is Needed
Storing a closure for later use requires @escaping:
var handlers: [() -> Void] = []
func register(_ handler: @escaping () -> Void) {
handlers.append(handler) // escapes the function
}
register { print("later") }
handlers[0]() // "later"Escaping with Async Work
Completion handlers escape because they run after the function returns:
func load(then completion: @escaping (String) -> Void) {
// imagine async work
completion("data")
}
load { result in print(result) } // "data"self Must Be Explicit
Inside an escaping closure you must write self. explicitly when accessing instance members — a reminder that the closure may retain self.
Explicit self in Escaping
The compiler requires the explicit reference:
class Loader {
var name = "L"
func start(_ done: @escaping () -> Void) {
let cb = { print(self.name); done() }
cb()
}
}
Loader().start { print("finished") } // "L" then "finished"Storing Many Callbacks
Escaping closures let you build observer lists:
class Emitter {
private var listeners: [(Int) -> Void] = []
func on(_ l: @escaping (Int) -> Void) { listeners.append(l) }
func fire(_ v: Int) { listeners.forEach { $0(v) } }
}
let e = Emitter()
e.on { print("got \($0)") }
e.fire(7) // "got 7"Returning a Stored Closure
Closures kept in properties are escaping:
class Button {
var action: (() -> Void)?
func setAction(_ a: @escaping () -> Void) { action = a }
}
let b = Button()
b.setAction { print("tapped") }
b.action?() // "tapped"Optional Closures Escape
An optional closure parameter is implicitly escaping (it is wrapped in Optional), so it can be stored:
func maybe(_ f: (() -> Void)?) {
f?()
}
maybe { print("ran") } // "ran"Escaping into an Array of Tasks
A queue of deferred work is a classic escaping use case — each closure is stored, then run later:
var tasks: [() -> Int] = []
func schedule(_ task: @escaping () -> Int) {
tasks.append(task)
}
schedule { 1 + 1 }
schedule { 10 * 2 }
print(tasks.map { $0() }) // [2, 20]Performance Note
Non-escaping closures can be optimized more aggressively (no heap allocation needed). Keep closures non-escaping when you can; only escape when you truly store or defer them.
func sum(_ xs: [Int], _ f: (Int) -> Int) -> Int {
xs.reduce(0) { $0 + f($1) } // non-escaping, fast
}
print(sum([1, 2, 3]) { $0 * $0 }) // 14Quick Check
When must a closure parameter be marked @escaping?
Recap
You learned escaping closures:
- Non-escaping is the default; closures run before the function returns
@escapingis required to store or defer a closure- Escaping closures require explicit
self.access - Optional closure params escape implicitly; prefer non-escaping for speed
Next: capture lists and weak self.
Frequently asked questions
Is the “Escaping Closures” lesson free?
Yes — the full text of “Escaping Closures” is free to read here on the web, and the Swift Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Swift Academy course, upgrade to CoddyKit PRO.
What will I learn in “Escaping Closures”?
Store closures that outlive their function. You practise Swift Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Swift Academy?
No prior experience is required. Swift Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Escaping Closures” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Swift Academy lesson?
Yes. Every Swift Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Capturing Values by Reference
- Escaping Closures
- Capture Lists and Weak Self
- Autoclosures