ios-swift
/

Swift Closures – Master Anonymous Functions

Last Sync: Today

On this page

5
0%
5 min read
Remaining
5 minleft

Click any section to jump — progress syncs automatically

ios-swift

Swift Closures – Master Anonymous Functions

What is a Closure?

Closures are self-contained blocks of functionality that can be passed around and used in your code. They can 'capture' and store references to variables and constants from the context in which they are defined. In Swift, functions are actually a special case of closures. As an Architect, you'll use closures primarily for completion handlers (callbacks) and functional programming patterns like map and filter.

  1. Closure Expression Syntax

Swift closures have a distinct syntax: { (parameters) -> return type in statements }. The in keyword is crucial as it separates the definition of the closure's parameters and return type from its body.

SWIFTRead-only
1
let calculateMarkup = { (price: Double, rate: Double) -> Double in
    return price * rate
}

let total = calculateMarkup(100.0, 0.2) // Returns 20.0

  1. Trailing Closure Syntax

If a closure is the final argument to a function, Swift allows you to 'pop' it out of the parentheses. This makes the code look much cleaner and more like a standard block of code, which is a common pattern in SwiftUI.

SWIFTRead-only
1
// Standard way
performAction(name: "Build", action: { print("Building...") })

// Trailing closure way (Preferred)
performAction(name: "Build") { 
    print("Building...") 
}

  1. Escaping Closures (@escaping)

By default, closures are 'non-escaping,' meaning they are executed within the function they are passed to. If a closure needs to be stored and executed after the function returns (like a network request callback), you must mark it as @escaping. This is a vital safety feature that helps the compiler manage memory.

  1. Memory Management: Capture Lists

Closures can cause Strong Reference Cycles (Memory Leaks) because they hold onto the objects they use. To prevent this, Architects use 'Capture Lists' to define how the closure should interact with the surrounding scope, usually by marking self as weak or unowned.

SWIFTRead-only
1
class ProjectUploader {
    var onComplete: (() -> Void)?

    func start() {
        // Use [weak self] to prevent a memory leak
        onComplete = { [weak self] in
            self?.notifyUser()
        }
    }
    
    func notifyUser() { print("Upload finished") }
}

Test Your Knowledge

Q1
of 3

Which keyword separates a closure's signature from its body?

A
do
B
then
C
in
D
where
Q2
of 3

Which attribute is required for a closure that is called after the function it was passed to has already returned?

A
@escaping
B
@autoclosure
C
@discardableResult
D
@async
Q3
of 3

What is the primary purpose of using [weak self] in a closure's capture list?

A
To make the code execute faster
B
To prevent strong reference cycles (memory leaks)
C
To allow the closure to modify global variables
D
To hide the closure from other classes

Frequently Asked Questions

What are shorthand argument names like $0 and $1?

Swift provides shorthand names for inline closures. Instead of writing '(a, b) in a + b', you can simply write '$0 + $1'. This is excellent for simple transformations like 'array.sort { $0 > $1 }'.

Is a Closure the same as a Function?

Yes and no. All functions are closures, but functions have names and are defined with the 'func' keyword. Closures are generally anonymous and have a more flexible syntax for capturing variables.

When should I use 'unowned' vs 'weak' in a capture list?

Use 'weak' when the captured reference might become nil (it becomes an Optional). Use 'unowned' only when you are 100% certain the reference will never be nil while the closure exists; it's faster but crashes if the reference is gone.

Previous

swift collections

Next

swift async await

Related Content

Need help?

Explore our comprehensive docs or start a chat with our tech experts.