Core Concepts
Closures
Master Swift closures — self-contained blocks of functionality that capture their context.
What are Closures?
Closures are self-contained blocks of code that can be passed around and used in your code. They're similar to lambdas in other languages.
Swift closures can capture values from their surrounding scope.
Closure Syntax
Full syntax:
swift
{ (parameters) -> ReturnType in body }Swift allows progressively simplified syntax for trailing closures.
Capturing Values
Closures capture references to the variables and constants from the surrounding context. This is powerful but requires care with [weak self] to avoid retain cycles.
Example
swift
// Full closure syntax
let add: (Int, Int) -> Int = { (a: Int, b: Int) -> Int in
return a + b
}
// Simplified - infer types
let multiply: (Int, Int) -> Int = { a, b in a * b }
// Even shorter - shorthand argument names
let square: (Int) -> Int = { $0 * $0 }
print(add(5, 3)) // 8
print(multiply(4, 5)) // 20
print(square(7)) // 49
// Closures with higher-order functions
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let evens = numbers.filter { $0 % 2 == 0 }
let doubled = numbers.map { $0 * 2 }
let sum = numbers.reduce(0) { $0 + $1 } // or reduce(0, +)
// Trailing closure syntax
let sorted = numbers.sorted { $0 > $1 } // descending
// Capturing values
func makeCounter(start: Int = 0) -> () -> Int {
var count = start // captured by the closure
return {
count += 1
return count
}
}
let counter = makeCounter(start: 10)
print(counter()) // 11
print(counter()) // 12
print(counter()) // 13
// Escaping closures (stored and called later)
var completionHandlers: [() -> Void] = []
func doSomething(completion: @escaping () -> Void) {
completionHandlers.append(completion)
}
// Avoid retain cycles with [weak self]
class MyView {
func loadData() {
fetchData { [weak self] result in
guard let self = self else { return }
self.updateUI(with: result)
}
}
}Try it yourself — SWIFT