Closure in Swift

Block很像,表示代码的集合,简称代码块。

可以被传递,不会马上被执行,当然后期可以被执行多次。

NSURLSessioncompletionHandler就是一个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 escapeclosure,后续再补充:

你可能感兴趣的:(Closure in Swift)