跟Block
很像,表示代码的集合,简称代码块。
可以被传递,不会马上被执行,当然后期可以被执行多次。
NSURLSession
的completionHandler
就是一个closure
对象,这个对象会在NSURLSession
收到了服务器的返回数据或者错误信息之后被执行。
一般closure
有下面两种:
{ parameters in
//Code
}
或者没有参数的版本:
{
//Code
}
第一种中,in
关键字分割了参数,就像函数和方法那样,closure
可以接收参数,在in
关键字之前,而且不需要指明参数类型,如果想要指明参数类型也可以:
下面是指明了closure
的参数类型的声明方法:
let dataTask = session.dataTaskWithURL(url, completionHandler: {
(data: NSData?, response: NSURLResponse?, error: NSError?) in
...
})
在closure
代码中,可以使用 $0 $1 $2 来代替参数。
如果调用的方法的最后一个参数是一个closure
,那么可以对掉用进行简写:
let dataTask = session.dataTaskWithURL(url) {
data, response, error in
...
}
不简写的版本是:
let dataTask = session.dataTaskWithURL(url, completionHandler:{
data, response, error in
...
})
简写的版本更加易读。
closure
也可以用作 初始化对象 和lazy loading
lazy var dateFormatter: NSDateFormatter = {
let formatter = NSDateFormatter()
formatter.dateStyle = .MediumStyle
formatter.timeStyle = .ShortStyle
return formatter
}()
在Swift
中所有的 方法 都是closure
,可以直接将一个已有的方法当做closure
在参数中进行传递,只要 参数列表是匹配的。
let dataTask = session.dataTaskWithURL(url,
completionHandler: myCompletionHandlerMethod)
func myCompletionHandlerMethod(data: NSData?,
response: NSURLResponse?, error: NSError?) {
...
}
closure
会捕获所有在内部使用的变量,包括self
,会有几率造成引用循环和内存泄露,解决方法:
let dataTask = session.dataTaskWithURL(url) {
[weak self] data, response, error in
...
}
最后:Swift
支持一种no escape
的closure
,后续再补充: