Swift中被忽略的@noescape

这里需要先介绍一下escape的概念。当一个闭包当做一个参数传进函数里,这个闭包是在这个函数执行完后执行的,这个时候我们就说这个闭包从函数逃出来了(escape)。这种场景很常见,比如我们进行一个异步的请求,请求时会传入一个handler,比如当请求成功后执行达到回调的目的。

众所周知swift的内存管理是引用计数。闭包里用到的数据都需要捕捉到闭包里,保证闭包执行时这些数据不会被释放还在内存里。Xcode为了让我们意识到闭包里用到的对象其实已经被retain了,就要求我们访问当前属性时显示声明self。
这个时候如果新手就很容易犯引用循环的错误。闭包retain了self,self如果又持有retain了闭包。最后就谁都释放不了,内存就泄露了。

这是swift中默认闭包的使用场景。
但是这里是有另外一种可能,假设有一个闭包是传入用于sort用的,或者比如作为map参数的闭包。当这行代码执行完成时,这个闭包也就使用完了,之后不会再被执行。这个情况下,闭包就不必再持有里面用到的对象。
这就是非escape闭包。

swift里针对非escape用@noescape表示。
比如map函数就使用了:
<pre><code>
func map<T>(@noescape transform: (Self.Generator.Element) throws -> T) rethrows -> [T]
</code></pre>
这样标记之后能看到的好处就是这个闭包里如果再使用self的属性不需要加<code>self.</code>了。对于编译器而言,在知道是noescape闭包后可以进行一些内存的优化。

欢迎关注我的微博:@没故事的卓同学

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 86.复合 Cases 共享相同代码块的多个switch 分支 分支可以合并, 写在分支后用逗号分开。如果任何模式...
    无沣阅读 5,303评论 1 5
  • 在上一篇文章Swift中的变量和常量中我总结了一些自己对于变量和常量的认识,最近学习了闭包,顺便给大家分享一下关于...
    老板娘来盘一血阅读 18,821评论 16 87
  • 转载自:https://github.com/Tim9Liu9/TimLiu-iOS[https://github...
    香橙柚子阅读 12,881评论 0 36
  • 你欠某个人的,会有另一个人要回去。某个人欠你的,会有另一个人还给你。你对某个人做的事,不管是伤害还是付出,总会由另...
    糖僧阅读 1,365评论 0 0
  • 今天目的地长春 哈尔滨的堵车很严重,8公里的路程走了一个小时,究其原因就是不守规矩的人太多了…… 十点进入拉林河收...
    安英雅集阅读 1,904评论 0 1