I've updated my code to Xcode 8.0 beta 6 but I got stuck with what seems to be about the new non escaping closure default. In the following code Xcode suggests to add @escaping
in front of completion:
in the first line of the below code, but that still won't compile and goes in circles. *
(EDIT: In fact, @escaping should be added in after completion:
, as Xcode suggests. The alert may still show but cleaning and compiling will remove it.)* How should this code be re-written / fixed to work in the updated Swift 3? I've had a look in the new manual but I couldn't find proper code samples.
func doSomething(withParameter parameter: Int, completion: () -> ()) { // Does something callSomeOtherFunc(withCompletion: completion) } // Calling the method and execute closure doSomething(withParameter: 2) { // do things in closure }
Any help much appreciated!
Escaping closures are different from non-escaping closures since we can preserve escaping closures to execute them later on. Meanwhile, the function body can execute and returns the compiler back. The scope of the escaping closure exists and has existence in memory as well until it gets executed.
In Swift, a closure marked with @escaping means the closure can outlive the scope of the block of code it is passed into. In a sense, @escaping tells the closure to “stay up even after the surrounding function is gone”.
In Swift, closures are non-escaping by default. This means that the closure can't outlive the function it was passed into as a parameter. If you need to hold onto that closure after the function it was passed into returns, you'll need to mark the closure with the keyword @escaping.
Closures as Function Parameter In Swift, we can create a function that accepts closure as its parameter. Here, search - function parameter. () -> () - represents the type of the closure.
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."
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With