0Pricing
Swift Academy · Lesson

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 })  // 14

Quick 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
  • @escaping is 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

  1. Capturing Values by Reference
  2. Escaping Closures
  3. Capture Lists and Weak Self
  4. Autoclosures
← Back to Swift Academy