@escaping 的作用

在阅读 Swift 代码时候,我们可以看到在方法中的有些 Closure 参数被声明为 @escaping,那么它的作用具体是做什么的?它和 @nonescaping 有什么区别?

版本更新历史

在 Swift 3.0 之前,方法中的参数默认为 @escaping,而在 Swift 3.0 之后,则修改默认修饰为 @nonescaping,你可以在这里看到相关提案 0103-make-noescape-default.md

@nonescaping closures:

当传递 Closure 作为方法参数时,Closure 将随着方法的结束而结束,并且在内存中也不存在。

@nonescaping closures 生命周期:

  1. 在方法调用期间,将 Closure 作为方法参数传递。
  2. 在方法中顺序执行一些操作,且运行 Closure。
  3. Closure 执行的结果会立即返回,在方法执行完成前也可能返回。

@escaping closures:

当传递 Closure 作为函数参数时,方法被执行完成后返回结果,但是 Closure 会依然保存在内存中,直到 Closure 被执行为止,且在 Closure 中可以进行变量存储。

  • 使用场景:
    • 存储:当您需要在方法执行完成后,依然保留 Closure 在内存中等待执行(比如等待API响应)
    • 异步执行:当您在发送队列上异步执行闭包时,队列将为您保留内存中的闭包,以便将来使用。 在这种情况下,您不知道何时将执行闭包。

@escaping closures 生命周期:

  1. 在方法调用期间,将 Closure 作为方法参数传递。
  2. 在方法中顺序执行一些操作,不一定执行 Closure。
  3. Closure 执行的结果会立即返回,在方法执行完成前也可能返回。

使用 @nonescaping closures 好处:编译器会优化你的代码,如果编译器知道这个闭包是不可逃逸的,它可以关注内存管理的关键细节。

而且你可以在 @nonescaping closures 放心使用 self 关键字,因为这个闭包总是在函数return之前执行,你不需要去使用一个修饰词去引用 self 这对于阅读和编写可靠的代码非常有帮助。

发表评论

电子邮件地址不会被公开。 必填项已用*标注