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

时间:2015-11-18 12:13:43

标签: ios swift closures

我的功能有这个签名:

self

现在我想在给定的闭包内逃避func foo(bar: String, @noescape baz: ((String) -> ())? = nil) 。 但是当我尝试这个时:

@noescape may only be applied to parameters of function type

编译器抱怨:

ConcurrentDictionary<..., StrongBox<int>> dict = ...;
Interlocked.Increment(ref dict[...].Value);

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

1 个答案:

答案 0 :(得分:10)

要求

如果您的要求如下:

  • baz param是closure
  • baz param标有@noescape(因为您想在闭包代码中省略self
  • 在调用baz
  • 期间可以省略foo param

解决方案

然后您可以使用以下语法

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

}

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

  • 此处baz不是optional type(但它是&#34;可选参数&#34;)
  • ,其默认值为empty closure,而非nil值。

实施例

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

class Boo {
    let world = "world"
    func boo() {
        foo("hello") { (something) -> () in
            print(world)
        }
    }
}

您还可以省略baz param

class Boo {
    let world = "world"
    func boo() {
        foo("hello")
    }
}

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

在下面的评论中,用户TadeasKriz询问如何将此方法与返回值与Void不同的闭包使用。

这是解决方案

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

}

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

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

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

或者,您可以完全省略baz param。

class Boo {
    let world = "world"
    func boo() {
        foo("hello")
    }
}