Optional closing parameter with fast speed 3

Given:

typealias Action = () -> () var action: Action = { } func doStuff(stuff: String, completion: @escaping Action) { print(stuff) action = completion completion() } func doStuffAgain() { print("again") action() } doStuff(stuff: "do stuff") { print("swift 3!") } doStuffAgain() 

Is there a way to make a completion (and action ) parameter of type Action? as well as save @escaping ?

Changing the type gives the following error:

error: @escaping attribute only applies to function types

Removing the @escaping attribute, the code compiles and runs, but does not seem correct, since closing completion speeds up the scope of the function.

+140
function closures swift3 optional
Sep 21 '16 at 14:01
source share
5 answers

SR-2552 reports that @escaping does not recognize a function type alias. therefore @escaping attribute only applies to function types error @escaping attribute only applies to function types . You can get around this by expanding the type of the function in the function signature:

 typealias Action = () -> () var action: Action? = { } func doStuff(stuff: String, completion: (@escaping ()->())?) { print(stuff) action = completion completion?() } func doStuffAgain() { print("again") action?() } doStuff(stuff: "do stuff") { print("swift 3!") } doStuffAgain() 

EDIT 1 :

I was actually under beta version of xcode 8 where the error SR-2552 has not yet been resolved. correcting this error, introduced a new one (the one you encountered) that is still open. see SR-2444 .

The @Michael Ilseman workaround indicated that a workaround is to remove the @escaping attribute from an optional function type that saves the function as an escape one .

 func doStuff(stuff: String, completion: Action?) {...} 

EDIT 2 :

SR-2444 was closed, specifically indicating that closing in position parameters cannot be avoided, and it is necessary that they be marked with @escaping to make them escape, but optional parameters are implicitly avoided, since ((Int)->())? is synonymous with Optional<(Int)->()> , additional closures screen.

+100
Sep 21 '16 at 14:21
source share

from: fast users mailing list

In principle, @escaping is only valid for closures in the position of function parameters. The noescape-by-default rule applies only to these closures in the function parameter position, otherwise they are escaped. Aggregates, such as enumerations with associated values ​​(for example, optional), tuples, structures, etc. If they have closures, follow the default rules for closures that are not in the position of the function parameters, that is, they slip away.

Thus, the optional parameter of the function is @escaping by default.
@noeascape by default applies only to function parameters.

+181
Oct 04 '16 at 7:26
source share

I am facing a similar problem, and because mixing @escaping and non @escaping is very confusing, especially if you need to go through a close. I end up with default options (which I think makes more sense)

 func doStuff(stuff: String = "do stuff", completion: @escaping (_ some: String) -> Void = { _ in }) { completion(stuff) } doStuff(stuff: "bla") { stuff in print(stuff) } doStuff() { stuff in print(stuff) } 
+15
Nov 17 '16 at 15:51
source share

I got it in Swift 3 without any warnings just this way:

 func doStuff(stuff: String, completion: (()->())? ) { print(stuff) action = completion completion?() } 
+15
Jul 17 '17 at 20:32
source share

In this example, it is important to understand that if you change Action to Action? closing escapes. So let's do what you suggest:

 typealias Action = () -> () var action: Action? = { } func doStuff(stuff: String, completion: Action?) { print(stuff) action = completion completion?() } 

Ok, now we will call doStuff :

 class ViewController: UIViewController { var prop = "" override func viewDidLoad() { super.viewDidLoad() doStuff(stuff: "do stuff") { print("swift 3!") print(prop) // error: Reference to property 'prop' in closure // requires explicit 'self.' to make capture semantics explicit } } } 

Well, this requirement only arises to avoid short circuits. So the closure is slipping away. That is why you do not mark him as an escape - he has already escaped.

0
Jun 14 '19 at 22:08
source share



All Articles