Swift optional escaping closure parameter

Lescai Ionel picture Lescai Ionel · Sep 21, 2016 · Viewed 59.2k times · Source

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 any way to make the completion parameter (and action) of type Action? and also keep @escaping ?

Changing the type gives the following error:

@escaping attribute only applies to function types

Removing the @escaping attribute, the code compiles and runs, but doesn't seem to be correct since the completion closure is escaping the scope of the function.

Answer

Dmitry Coolerov picture Dmitry Coolerov · Oct 4, 2016

from: swift-users mailing list

Basically, @escaping is valid only on closures in function parameter position. The noescape-by-default rule only applies to these closures at function parameter position, otherwise they are escaping. Aggregates, such as enums with associated values (e.g. Optional), tuples, structs, etc., if they have closures, follow the default rules for closures that are not at function parameter position, i.e. they are escaping.

So optional function parameter is @escaping by default.
@noeascape only apply to function parameter by default.