鉴于:
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()
有什么方法可以使completion参数(和action)的类型Action?也保持不变@escaping?
completion
action
Action?
@escaping
更改类型会出现以下错误:
@escaping属性仅适用于函数类型
删除该@escaping属性后,代码将编译并运行,但由于completion闭包使函数的作用范围变大,因此似乎并不正确。
有一个SR-2552报告@escaping无法识别功能类型别名。这就是错误的原因@escaping attribute only applies to function types。您可以通过扩展函数签名中的函数类型来解决:
@escaping attribute only applies to function types
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()
编辑1 :
我实际上是在xcode 8 beta版本下,但尚未解决bug SR-2552。修复了该错误,并引入了一个仍在打开的新错误(您面临的错误)。参见SR-2444。
解决方法 @迈克尔Ilseman 指出作为临时解决方案是去除@escaping从可选功能类型的属性, 其保持功能逸出 。
func doStuff(stuff: String, completion: Action?) {...}
编辑2 ::
该SR-2444已经被关闭,说明明确,在参数位置关闭 不 逃逸,需要他们被打上@escaping让他们逃脱,但可选参数 都 隐含逃避,因为((Int)->())?是同义词Optional<(Int)->()>,可选的闭包逃跑。
((Int)->())?
Optional<(Int)->()>