一尘不染

Swift可选的转义闭包参数

swift

鉴于:

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

更改类型会出现以下错误:

@escaping属性仅适用于函数类型

删除该@escaping属性后,代码将编译并运行,但由于completion闭包使函数的作用范围变大,因此似乎并不正确。


阅读 332

收藏
2020-07-07

共1个答案

一尘不染

有一个SR-2552报告@escaping无法识别功能类型别名。这就是错误的原因@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)->()>,可选的闭包逃跑。

2020-07-07