在Swift中转义和不转义闭包

对于那些使用闭包的人,您可能会遇到@escaping或@nonescaping。 这他妈到底是什么? 为了理解这两个概念,让我们刷新记忆,看看根据Apple文档的闭包。

闭包是可以独立传递的功能块,可以在代码中传递和使用。

无漏封

非逃避封闭的生命周期

  1. 将闭包传递给函数
  2. 该函数执行该关闭
  3. 函数返回

基本上,非转义的闭包只能运行其主体内部的内容,而不能使用其外部的任何内容。 非转义闭包告诉编译器,您传入的闭包将在该函数的主体内执行,而在其他任何地方都不会执行。 函数结束时,闭包将不再存在于内存中。 例如,如果我们需要提取闭包内的任何值以在其外部使用,则我们可能不这样做。 在Swift的早期,默认情况下会关闭转义参数。 由于更好的内存管理和优化,Swift将所有闭包默认更改为不转义。

  varclosuresArray:[()->无效] = [] 
  func doClosures(completion:()-> Void){ 
  completeHandlers.append(完成) 
  } 
  //错误!!! 
将非转义参数“ completion”传递给需要@转义闭包的函数

这是一个非转义闭包的示例。 在这里,我们有一个空的闭包数组和一个包含闭包的函数。 如果要将函数中的闭包附加到闭包数组,则不能这样做,因为默认情况下它是非转义符。 Xcode的一大优点是您将需要一个转义的闭包并可以为您实现它。

逃逸关闭

本质上,转义的闭包与非转义的闭包相反。 逸出的闭包使闭包具有超过该功能的能力,并且可以存储在其他位置。 通过使用转义闭包,闭包将一直存在于内存中,直到执行完所有内容为止。 要实现转义闭包,我们要做的就是将@escaping放在闭包前面。 如果您不确定关闭是否需要转义,就不用担心,就像我在编译器足够聪明地告诉您之前所说的那样。

当我们需要实现转义闭包时,有几种方法。 一种情况是使用异步执行。 当我们处理调度队列时,该队列将为您保留关闭,而当队列完成其工作后,它将返回到关闭并完成它。 由于调度队列不在范围内,因此我们需要使用转义闭包。 另一个例子是,当我们需要将闭包存储到全局变量,属性或函数之后的任何存储中。