解释 Swift 闭包语法

Explain Swift Closure syntax

我是 Swift 和闭包的新手,正在寻求一些帮助以了解到底发生了什么。

示例 1:

func getData(completionHandler: ((NSArray?, NSError?) -> Void)?) -> Void {

所以函数getData有一个完成句柄,其中NSArray + NSError是传递给函数的可选参数?下面的位 -> Void)? 是否表明 return 类型是无效的,即没有任何内容被设置为 returned 并且整个闭包是可选的?

然后我不确定在这种情况下 -> Void meant 以下是什么?

示例 2:

let task = session.dataTaskWithURL(url!, completionHandler: {data, response, error -> Void in
... do something
}

在这种情况下,completionHandler 数据、响应和错误在块内分配给常量 task。那是对的吗?我不确定 -> Void inerror 的关系,尤其是附加的 in?

我花了一段时间查看各种代码,甚至自己编写了一些代码来熟悉语法,但是当我发现时很容易感到困惑 http://fuckingclosuresyntax.com/

您对方法签名的看法是正确的。 -> Void)? 表示传入完成处理程序是可选的。 Void 表示该块不应该 return 一个供其调用者使用的值,这一点毫无意义。完成处理程序类型有一个闭包(匿名函数)类型,它正好接受 2 个参数:一个可选的 NSArray 类型和一个可选的 NSError 类型(所以 either/both 其中一个可能为零)。它 return 对来电者来说无关紧要。

在你的第二个例子中,你实际上是在创建一个完成处理程序来传递给 dataTaskWithURL 方法,使用 data, response, error 作为参数(更多关于语法)。 -> Void 和以前一样,表明你的块 return 什么都没有,尽管它在 error 旁边。 in 只是用作编译器的分隔符,用于将闭包的参数与其主体分开。这种语法甚至有一点简写。我通常总是在块参数周围使用括号,但我想这取决于个人 style/taste/whatever。因此,您的 completionHandler 定义也可能如下所示:

{ (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in // code, end with a }

现在更清楚是怎么回事了。 Swift 做了很多推理,让你写得漂亮而紧凑,但如果你不熟悉代码,它可能会隐藏一些意义。这是定义一个闭包,它接受 3 个隐式展开的可选值作为参数:NSData! 类型之一,NSURLResponse! 类型之一,以及 NSError! 类型之一。 return没什么(-> Void)。闭包的主体,即无论你想做什么,都在 in 之后直到下一个 }。因为该方法准确定义了将要传递到块中的类型,所以在实现中,参数可以通过省略类型注释来简单地推断它们的类型,从而从 data: NSData! 变为 data。同样在 Swift 中,省略闭包参数周围的括号是有效的,留下原始代码行。