Updating closures to Swift 3 – @escaping

Swift 3: closure parameter attributes are now applied to the parameter type, and not the parameter itself

Prior to Swift 3, the closure attributes @autoclosure and @noescape used to be attributes to the closure parameter, but are now attributes to the parameter type; see the following accepted Swift evolution proposal:

Your specific question pertain to parameter type attribute @escaping (for which the same new rule applies), as described in the accepted Swift evolution proposal to let closure parameters be non-escaping by default:

These proposals are now both implemented in the beta stage of Xcode 8 (see release notes for Xcode 8 beta 6; dev. account login needed for access)

New in Xcode 8 beta 6 – Swift Compiler: Swift Language

Closure parameters are non-escaping by default, rather than explicitly
being annotated with @noescape. Use @escaping to indicate that a
closure parameter may escape. @autoclosure(escaping) is now written as
@autoclosure @escaping. The annotations @noescape and
@autoclosure(escaping) are deprecated. (SE-0103)

New in Xcode 8 beta – Swift and Apple LLVM Compilers: Swift Language

The @noescape and @autoclosure attributes must now be written
before the parameter type instead of before the parameter name. [SE-0049]

Hence, you use the non-default @escaping attribute as follows; applied to the type of the closure parameter, rather than the parameter itself

func doSomething(withParameter parameter: Int, completion: @escaping () -> ()) {
    // ...
}

(Including my answer to a question in an upvoted comment below, as comments are not persistent data on SO)

@Cristi Băluță: “What does escaping do? Never seen this keywords
before swift3 auto-conversion … “

See e.g. the link to the SE-0103 evolution proposal above (as well as the quoted text from the beta 6 release notes): previously, closure parameters were escaping by default (hence no need for the existence of an explicit annotation for escaping), but are now instead non-escaping, by default. Hence the addition of @escaping to explicitly annotate that a closure parameter may escape (contrary to its default behaviour). This also explains why @noescape is now deprecated (no need to annotate the default behaviour).

For explaining what it means that a closure parameter is escaping, I quote the Language Reference – attributes:

“Apply this attribute to a parameter’s type in a method or function declaration to indicate that the parameter’s value can be stored for
later execution. This means that the value is allowed to outlive the
lifetime of the call.”

Leave a Comment