如何将@noescape注释添加到可选的闭包中

gfp*_*eco 10 closures ios swift

我的功能有这个签名:

func foo(bar: String, baz: ((String) -> ())? = nil)
Run Code Online (Sandbox Code Playgroud)

现在我想self在给定的闭包内部进行必要的逃避.但是,当我尝试这个:

func foo(bar: String, @noescape baz: ((String) -> ())? = nil)
Run Code Online (Sandbox Code Playgroud)

编译器抱怨:

@noescape may only be applied to parameters of function type
Run Code Online (Sandbox Code Playgroud)

是否可以在可选参数中使用它?

Luc*_*tti 10

要求

如果您的要求如下:

  • baz参数是一个closure
  • baz参数是标有@noescape(因为要省略self在封闭代码)
  • 所述bazPARAM可以的调用期间被省略foo

然后,您可以使用以下语法

func foo(bar: String, @noescape baz: ((String) -> ()) = { _ in } ) {

}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,与您的代码的主要区别在于:

  • 这里baz不是optional type(但它是一个"可选参数")
  • 它的默认值empty closure不是nil值.

例子

根据您的要求,您现在可以将闭包传递给它baz而无需使用self

class Boo {
    let world = "world"
    func boo() {
        foo("hello") { (something) -> () in
            print(world)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你也可以省略baz参数

class Boo {
    let world = "world"
    func boo() {
        foo("hello")
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:使用返回类型与Void不同的闭包

在下面的评论中,用户TadeasKriz询问如何使用具有返回值不同的闭包的方法Void.

这是解决方案

func foo(bar: String, @noescape baz: ((String) -> (Int)) = { _ in return 0 } ) {

}
Run Code Online (Sandbox Code Playgroud)

这里bazparam需要一个带有1个类型参数和类型String返回值的闭包Int.正如您所看到的,我向param添加了一个默认值,一个确实返回的闭包0.请注意,永远不会使用默认闭包,因此您可以替换0Int您想要的任何值.

现在您可以决定是否使用将闭包传递给baz参数

class Boo {
    let world = "world"
    func boo() {
        foo("hello") { (something) -> Int in
            print(world)
            return 100
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,再次,你可以完全省略baz参数.

class Boo {
    let world = "world"
    func boo() {
        foo("hello")
    }
}
Run Code Online (Sandbox Code Playgroud)