
"Can you explain what a closure is in Swift, how it captures values from its surrounding scope, and give a simple example of using one?"
A closure in Swift is a self-contained block of functionality that can be passed around and executed later. It is similar to a function, but closures are especially useful when treated as values.
let greet = { print("Hello") }
greet()
Closures can capture and store references to constants and variables from the surrounding scope. This allows the closure to keep using those values even after the original scope has finished executing.
func makeCounter() -> () -> Int {
var count = 0
return {
count += 1
return count
}
}
Swift supports several closure syntax shortcuts, including type inference, implicit returns for single-expression closures, and shorthand argument names like $0 and $1. These features make closures concise, especially in collection operations.
let nums = [1, 2, 3]
let doubled = nums.map { \$0 * 2 }
A non-escaping closure is executed before the function returns, while an escaping closure may be stored and executed later. Escaping closures require the @escaping keyword and are common in asynchronous code.
func fetchData(completion: @escaping () -> Void) {
DispatchQueue.main.async {
completion()
}
}
Closures can capture self strongly, which may create retain cycles when the closure is stored by an object it references. Swift uses capture lists like [weak self] to avoid memory leaks in these cases.
service.load { [weak self] in
self?.updateUI()
}