在学习Swift 3的过程当中整理了一些笔记,若是想看其余相关文章可前往《Swift 3必看》系列目录git
在以前,一个函数的参数的闭包的捕捉策略默认是escaping,若是是一个非逃逸闭包须要显示的添加声明@noescape。感兴趣的能够看我之前写过一篇介绍:Swift中被忽略的@noescape。简单的介绍就是若是这个闭包是在这个函数结束前内被调用,就是非逃逸的即noescape。若是这个闭包是在函数执行完后才被调用,调用的地方超过了这函数的范围,因此叫逃逸闭包。github
举个例子就是咱们经常使用的masonry或者snapkit的添加约束的方法就是非逃逸的。由于这闭包立刻就执行了。json
public func snp_makeConstraints(file: String = #file, line: UInt = #line, @noescape closure: (make: ConstraintMaker) -> Void) -> Void {
ConstraintMaker.makeConstraints(view: self, file: file, line: line, closure: closure)
}复制代码
网络请求请求结束后的回调的闭包则是逃逸的,由于发起请求后过了一段时间后这个闭包才执行。好比这个Alamofire里的处理返回json的completionHandler闭包,就是逃逸的。swift
public func responseJSON( queue queue: dispatch_queue_t? = nil, options: NSJSONReadingOptions = .AllowFragments, completionHandler: Response<AnyObject, NSError> -> Void)
-> Self
{
return response(
queue: queue,
responseSerializer: Request.JSONResponseSerializer(options: options),
completionHandler: completionHandler
)
}复制代码
就像我以前写的那篇标题,不少人在写闭包参数的时候老是忽略去判断这个闭包是不是逃逸的。这对闭包的内存管理优化不太友好,都被当作了逃逸闭包处理。因此在3中作出了一个对调的改变:全部的闭包都默认为非逃逸闭包,再也不须要@noescape;若是是逃逸闭包,就用@escaping表示。好比下面的一段代码,callBack在函数执行完后1秒才执行,因此是逃逸闭包。api
func startRequest(callBack: ()->Void ) {
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 1) {
callBack()
}
}复制代码
这样就须要显示的声明@escaping才能编译经过。网络