Swift closure — @escaping Vs @noescape

Imad Ali Mohammad
2 min readMay 24, 2024

--

Closure Keywords

Closures in Swift are first-class citizens, which means they can be treated like any other type (such as strings, integers, and classes). They are often used for functional programming patterns, such as mapping and filtering arrays, and for asynchronous programming. They can also be passed as arguments to functions and can be returned from functions as well. Closures are a powerful and flexible feature of Swift, and they are used extensively in the language’s standard library and APIs.

@escaping

This annotation is used when a closure is allowed to escape the scope in which it’s defined. It means that the closure can be stored and executed at a later time, even after the function it’s passed to has returned. This is typically used when the closure is stored in a property, passed as an argument to another function, or retained beyond the lifetime of the function it’s defined in.

func someFunction(completion: @escaping () -> Void) {
DispatchQueue.main.async {
completion()
}
}

var completionHandlers: [() -> Void] = []

func someOtherFunction() {
someFunction {
print("Closure has escaped")
}
}

@noescape

This annotation indicates that the closure won’t outlive the function it’s passed to. It’s the default behavior in Swift 3 and later, so you don’t need to explicitly annotate a closure as @noescape unless you're writing Swift 2 code. This can be used for performance optimization because the compiler can make assumptions about the closure's lifespan, potentially leading to better optimization opportunities.

From Swift 3 onwards, closures are non-escaping by default, can be use @escaping if not what we want. Non-escaping closure defiantly will execute before the function returns.

func performOperation(operation: () -> Void) {
operation()
}

func callingFunction() {
performOperation {
print("This closure won't escape the function")
}
}

Note: 📣 Always remember to use weak self while using a closure to aviod retain cycles. ⚠ ️(Like { [weak self] item in ….}

In summary, @escaping is used to indicate that a closure can outlive the function it's defined in, while @noescape (though implicit in Swift 3 and later) signifies that a closure is restricted to the scope of the function it's passed to.

--

--

Imad Ali Mohammad
Imad Ali Mohammad

Written by Imad Ali Mohammad

Senior iOS Engineer, Passionate about coding and building amazing apps.

No responses yet