我是Swift和关闭的新手,并且正在帮助确切了解发生了什么。
示例1:
func getData(completionHandler: ((NSArray?, NSError?) -> Void)?) -> Void {
所以函数getData
有一个完成处理程序,其中NSArray
+ NSError
是传递给函数的可选参数?以下位-> Void)?
返回类型是否为空,即没有设置为返回且整个闭包是可选的?
在那种情况下,我不确定以下-> Void meant
是什么?
示例2:
let task = session.dataTaskWithURL(url!, completionHandler: {data, response, error -> Void in
... do something
}
在这种情况下,completionHandler
数据,响应和错误在块内分配给常量task
。那是对的吗?我不确定与-> Void in
相关的error
,尤其是in
还有哪些?
我花了一段时间查看各种代码,甚至自己写一些来熟悉语法,但是很容易让我感到困惑,因为我发现http://fuckingclosuresyntax.com/
答案 0 :(得分:4)
您对方法签名是正确的。 -> Void)?
表示传入的完成处理程序是可选的。 Void
表示该块不应返回其调用者使用的值,这是值得的。完成处理程序类型有一个闭包(匿名函数)类型,它只有两个参数:一个是可选的NSArray
类型,另一个是可选的NSError
类型(所以这两个中的任何一个都可能是零)。它不向调用者返回任何内容。
在第二个示例中,您实际上正在创建一个完成处理程序以传递到dataTaskWithURL
方法,其中data, response, error
作为参数(更多关于语法的内容)。 -> Void
与之前相同,表示您的块没有返回任何内容,尽管它位于error
的旁边。 in
只是用作编译器的分隔符,用于将闭包的参数与其主体分开。这种语法甚至有点简短。我总是在块参数周围使用括号,但我认为这取决于个人风格/品味/其他。因此,您的completionHandler
定义也可能如下所示:
{ (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in // code, end with a }
现在它变得更清楚了。 Swift做了很多推理并允许你写得很好而且紧凑但如果你不熟悉代码它可以隐藏一些含义。这是一个闭包,它接受3个隐式解包的选项作为参数:NSData!
类型之一,NSURLResponse!
之一,NSError!
之一。它什么都不返回(-> Void
)。封闭的主体,即你想要做的任何东西,都在in
之后,直到下一个}
。因为该方法确切地定义了要传递到块中的类型,所以在实现中,参数可以通过省略类型注释来简单地推断它们的类型,从而从data: NSData!
转到data
。同样在Swift中,在闭包参数周围省略括号是有效的,让我们留下原始的代码行。