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!
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)
Hence, you use the non-default
@escaping
attribute as follows; applied to the type of the closure parameter, rather than the parameter itself(Including my answer to a question in an upvoted comment below, as comments are not persistent data on SO)
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:
@noescape
From xcode 8 beta 6
@noescape
is the default. Prior to that,@escaping
was the default. Anybody updating to swift 3.0 from previous versions might face this error.You can not store a
@noescape
closure inside a variable. Because if you can store a closure inside a variable, you can execute the closure from anywhere in your code. But@noescape
states that the closure parameter can not escape the body of the function.This will give compiler error in Xcode 8
This will compile ok (explicitly write
@escaping
)Benefits of
@noescape
:For details check out: Make non-escaping closures the default