iOS Closures – Part Two
This article provides an in‑depth exploration of Swift closures on iOS, covering their definition, three forms, practical use cases, underlying SIL generation, capture lists, context capture, storage mechanisms, escaping and autoclosure variants, and important memory‑management considerations such as reference cycles.
What Is a Closure
A Closure in Swift is an independent block of code that can be passed around and executed later, analogous to Block in Objective‑C or lambda in other languages. It can capture constants and variables from its surrounding context, and Swift manages the memory of captured values.
Forms of Closures
Named global closures that capture no values.
Named nested closures that capture values from the enclosing function.
Unnamed lightweight closures that infer parameters and capture values automatically.
Swift Optimizations for Closures
Parameter and return‑type inference from context.
Single‑line expression bodies without the return keyword.
Shorthand argument names.
Trailing‑closure syntax.
Typical Use Cases
Deferred execution.
Long‑running or background tasks.
Extending the lifetime of instances or objects.
Syntax Examples
General closure format:
// General format
{ (parameters) -> returnType in
statements
}
var successClosure: ([String: Int]) -> VoidTrailing closure (last parameter of a function):
func someMethod(closureName: (parameters) -> ReturnType) { ... }
// usage
func urlRequest(successBlock: ([String: Int]) -> Void) { ... }Escaping closure (called after the surrounding function returns):
func someFuncEscapingClosure(closure: @escaping (Parameters) -> ReturnType) { ... }
// example
func loadImageCompletion(closure: @escaping () -> Void) { ... }Autoclosure (no parameters, evaluated when used):
func haveBreakfast(for food: () -> String) { ... }Combined @autoclosure @escaping:
func someFuncAutoEscapeClosure(closure: @autoclosure @escaping () -> ReturnType) { ... }Generating SIL Files
Compiling a Swift file with swiftc -emit-sil produces SIL (Swift Intermediate Language), which reveals how closures are lowered. For example, a simple closure capturing a constant becomes an @closure #1 symbol in the SIL output.
Capture List
When a closure captures external variables, the compiler adds those variables as additional parameters to the closure’s internal function. Example:
let bdNum = 3
let printNum = { [bdNum] in let _ = bdNum }
printNum()The generated SIL shows the captured value being passed as an extra argument.
Capture Context
Closures that capture mutable state store that state in a heap‑allocated box. The box is a reference‑type structure containing a reference count and the captured value. The closure’s type changes from () -> Int to (@guaranteed { var Int }) -> Int , passing the box as an implicit argument.
Storing Captured Values
The box is represented in LLVM as a struct containing a HeapObject (reference count and kind) and the captured value. The compiler emits code that allocates the box, stores the initial value, and retains/releases the box as needed.
Reference‑Cycle Pitfalls
Closures capture strong references by default. If an object also holds a strong reference to the closure, a retain cycle occurs. The solution is to capture self weakly or unowned:
class Cat {
let name: String?
lazy var nickName: () -> String = { [unowned self] in
if let name = self.name { return "nick of \(name)" }
else { return "none of nick" }
}
init(name: String?) { self.name = name }
deinit { print("cat is deinitialized") }
}
var aCat: Cat? = Cat(name: "Tom")
print(aCat!.nickName())Using weak introduces a side table for weak references, which has a slight performance cost compared to unowned . Choose weak for short‑lived references and unowned for long‑lived ones.
References
The Swift Programming Language 5.5 Edition – https://docs.swift.org/swift-book/
SIL Documentation – https://github.com/apple/swift/blob/main/docs/SIL.rst#abstract
Swift open‑source code – IRGenModule.cpp
Sohu Tech Products
A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.