In Swift 3, the default attribute for closures is now
@noescape (with the keyword being deprecated), we now have to specify closures that escape from a function as
@escaping. There is a standard library function
withoutAcutallyEscaping 1 that:
Allows a nonescaping closure to temporarily be used as if it were allowed to escape.
So what does it mean for a closure to “escape” from a function?
A closure is said to escape a function when the closure is passed as an argument to the function, but is called after the function returns.
- Stored somewhere else
- Used at a later time
- Executed asynchronously
Here’s a sample of a closure that escapes from a function (in this case by executing asynchronously). This is a compile error:
There are however valid cases where you don’t want to specify
@escaping in the function type signature because you know that the block doesn’t actually escape or get copied anywhere else. The Swift stdlib documentation gives an example where a function takes two closures and executes them concurrently 1:
This is safe because the
.barrier flag forces the function to wait until both closures have completed executing, so by using the
withoutActuallyEscaping, we can keep the type signature for the function the same but still use the closures internally in an asynchronous manner: