美文网首页
逃逸闭包

逃逸闭包

作者: 枫叶1234 | 来源:发表于2017-11-28 14:38 被阅读15次

在学习Swift 3的过程中整理了一些笔记,如果想看其他相关文章可前往《Swift 3必看》系列目录

在之前,一个函数的参数的闭包的捕捉策略默认是escaping,如果是一个非逃逸闭包需要显示的添加声明@noescape。感兴趣的可以看我以前写过一篇介绍:Swift中被忽略的@noescape。简单的介绍就是如果这个闭包是在这个函数结束前内被调用,就是非逃逸的即noescape。如果这个闭包是在函数执行完后才被调用,调用的地方超过了这函数的范围,所以叫逃逸闭包。

举个例子就是我们常用的masonry或者snapkit的添加约束的方法就是非逃逸的。因为这闭包马上就执行了。

publicfuncsnp_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闭包,就是逃逸的。

publicfuncresponseJSON(        queue queue: dispatch_queue_t? =nil,        options: NSJSONReadingOptions = .AllowFragments,        completionHandler: Response -> Void)->Self{returnresponse(            queue: queue,            responseSerializer:Request.JSONResponseSerializer(options: options),            completionHandler: completionHandler        )    }

就像我之前写的那篇标题,很多人在写闭包参数的时候总是忽略去判断这个闭包是否是逃逸的。这对闭包的内存管理优化不太友好,都被当做了逃逸闭包处理。所以在3中做出了一个对调的改变:所有的闭包都默认为非逃逸闭包,不再需要@noescape;如果是逃逸闭包,就用@escaping表示。比如下面的一段代码,callBack在函数执行完后1秒才执行,所以是逃逸闭包。

funcstartRequest(callBack:()->Void) {DispatchQueue.global().asyncAfter(deadline:DispatchTime.now() +1) {        callBack()    }}

这样就需要显示的声明@escaping才能编译通过。

作者:没故事的卓同学

链接:http://www.jianshu.com/p/120069d493f5

來源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

相关文章

网友评论

      本文标题:逃逸闭包

      本文链接:https://www.haomeiwen.com/subject/bptebxtx.html