当前位置: 首页 > 知识库问答 >
问题:

Swift是一个可选的转义闭包参数

臧友樵
2023-03-14

鉴于:

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()

有什么方法可以使Action?类型的完成参数(和action)并且还保留@逃逸

更改类型会产生以下错误:

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

删除转义属性,代码将编译并运行,但似乎不正确,因为完成闭包正在转义函数的范围。

共有3个答案

岳嘉良
2023-03-14
匿名用户

我遇到了一个类似的问题,因为混合使用< code>@escaping和非< code>@escaping非常令人困惑,尤其是当您需要传递闭包的时候。

我最终通过={_在}为闭包参数分配了一个no-op默认值,我认为这更有意义:

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)
}

爱花蜂
2023-03-14

有一个SR-2552报告@逃逸无法识别函数类型别名。这就是为什么错误@逃逸属性仅适用于函数类型。您可以通过扩展函数签名中的函数类型来解决问题:

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版本下,其中错误SR-2552尚未解决。修复了那个错误,引入了一个仍然开放的新错误(您面临的错误)。请参阅SR-2444。

@Michael Ilseman指出的临时解决方案是从可选函数类型中删除@escaping属性,该属性将函数保持为转义。

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

编辑2::

SR-2444 已关闭,明确指出参数位置中的闭包不是转义的,需要用 @escaping 标记它们以使它们转义,但可选参数是隐式转义的,因为 ((Int)-

郑理
2023-03-14

来自:swift-用户邮件列表

基本上,@escaping仅在函数参数位置的闭包上有效。noescape-by default 规则仅适用于函数参数位置处的这些闭包,否则它们将被转义。聚合,例如具有关联值的枚举(例如可选),元组,结构等,如果它们具有闭包,则遵循不在函数参数位置的闭包的默认规则,即它们正在转义。

因此,可选函数参数默认为@escaping
@noeascape默认情况下仅适用于函数参数。

 类似资料:
  • 问题内容: 鉴于: 有什么方法可以使参数(和)的类型也保持不变? 更改类型会出现以下错误: @escaping属性仅适用于函数类型 删除该属性后,代码将编译并运行,但由于闭包使函数的作用范围变大,因此似乎并不正确。 问题答案: 有一个SR-2552报告无法识别功能类型别名。这就是错误的原因。您可以通过扩展函数签名中的函数类型来解决: 编辑1 : 我实际上是在xcode 8 beta版本下,但尚未解

  • 问题内容: 编译器错误Closure use of non-escaping parameter ‘completion’ may allow it to escape,这是有道理的,因为它将在函数 返回之后被调用。 但是,如果我将闭包设为可选,则不会出现编译器错误,那是为什么呢? 函数返回后仍可以调用闭包。 问题答案: Clarification: 为了理解这种情况,实现以下代码将很有用: 乍一

  • 问题内容: 我是Swift的新手,当我遇到转义的闭包时,我正在阅读手册。我根本没有得到手册的描述。有人可以简单地向我解释一下Swift中的转义闭包是什么。 问题答案: 考虑此类: 将传入的闭包分配给类中的属性。 现在是另一个类: 如果我调用,则闭包将存储在的实例中。由于是在闭包中捕获的,因此的实例还将对其具有很强的引用性。 基本上,这是逃脱的闭包的例子! 您可能想知道,“什么?那么封闭从何处逃脱到

  • 我有一个,其形式为: 但是我得到错误:< code >将非转义参数“someOtherClosure”传递给需要@escaping闭包的函数。 这两个闭包实际上都是不可转义的(默认情况下),并且显式地将添加到会产生一个警告,表明这是Swift 3.1中的默认值。 知道我为什么会得到这个错误吗?

  • 我知道Swift 3中的更改,其中@nonevinging是闭包的默认行为。 我已经成功地更改了有关更改的大部分代码,但我的代码中有一部分无法摆脱闭包使用非转义参数可能允许它转义编译错误。 我尝试过在updateHandler参数和UpdatedInProgressHandler typealias中添加@逃逸,但这似乎还不够。 有人能帮我找出问题的原因吗? 定义typealiases和函数的代码

  • 我有一个协议: 通过一个示例实现: 上面的代码在 Swift3 (Xcode8-beta5) 中编译和工作,但不再与 beta 6 一起使用。你能给我指出根本原因吗?