我所在的项目组 iOS 版本 App 进入收尾阶段,还是希望自己慢慢接触到 Swift,一点一点使用 Swift 重构甚至是重写。其中 “@escaping” 就是我遇到的问题之一,所以希望本篇文章作为自己的收获和笔记。
背景
先上段代码

这段代码作用于网络请求,自己想封装一下请求功能。
传参数为:URL 链接``请求参数
返回值为:成功请求的 JSON和请求失败的 Error
报错的关键字 Closure use of non-escaping parameter ‘success’ may allow it to escape,Parameter ‘success’ is implicitly non-escaping.
什么是 @escaping (逃逸)
先来段英文定义解(zhuang)释(xia)下(bi)
If a closure is passed as an argument to a function and it is invoked after the function returns, the closure is escaping.
大意为:
如果一个闭包被作为一个参数传递给一个函数,并且在函数 return 之后才被唤起执行,那么这个闭包是逃逸闭包
Swift_Programming_Language/Closures
什么是 @non-escaping (非逃逸)
可以将 @non-escaping 理解为:
如果这个闭包是在这个函数结束前内被调用,就是非逃逸的即 @noescape
需要记住的一点是:
在 Swift 1.0 和 Swift 2.0 时代,@escaping 是默认的。如果知道这个闭包函数是非逃逸的,可以使用 @noescape 来标记函数。
但是在 Swift 3.0,则反之,如果知道这个闭包函数是逃逸的,就必须用 @escaping 标记他。
使用场景
在自己写 Swift 中最常见的闭包两个例子是:
使用 Alamofire 封装网络请求 -> 逃逸闭包 -> 需加 @escaping 关键字
使用 SnapKit 库布局 -> 非逃逸闭包 ->无需加任何关键字(默认即为非逃逸闭包)
*这里可以将逃逸闭包理解为异步操作,非逃逸闭包理解为同步操作。
注意事项
@escaping 逃逸闭包
访问属性或调用方法时必须加 self ,而且要注意循环引用问题
闭包在函数 return 之后执行,即异步执行
@noescape 非逃逸闭包
闭包中默认属性
闭包在函数返回之前执行,即同步执行
逃逸闭包与非逃逸闭包 目的是明确的告诉编译器:这里是@escaping,
即逃逸闭包,能够最大程度上对编译器编译优化。
解决
我所处的状态为逃逸闭包,所以要在闭包前加入@escaping即可解决此问题。
