非转义闭包的实际用途是什么?

时间:2020-02-17 11:04:44

标签: swift closures

如果函数本身可以返回值,那么为什么需要调用非转义闭包来返回值? 考虑以下示例

 func add(a: Int, b: Int, completion: (Int) -> ()) {
        let addition = a + b
        completion(addition)
 }

2 个答案:

答案 0 :(得分:2)

用于关闭的常见用例是:

  1. 异步调用;网络。

  2. 函数存储为变量;思考动作和提供的回调。

  3. 在调度队列上调度任务。

如果有一个过程需要一些时间才能完成工作并退还结果。在这些情况下,关闭是最佳选择。

非逃逸关闭

非转义的闭包具有非常清晰的生命周期,因此已成为Swift 3中的默认闭包类型。无转义的闭包很简单:将其传递给函数(或其他包含范围的函数),函数/作用域执行该闭包,然后函数返回。在调用函数的主体返回之后,闭包无法返回或完成执行。因此,编译器能够在转义的闭包之上优化非转义的闭包。

默认关闭行为(不可转义)

说一个简单的函数,像这样关闭:

func macICanBuy(budget: Int, closure: (String) -> Void) {
  print("checking budget...")

  closure("Mcdonalds' Big Mac")

  print("macICanBuy finished execution")
}

override func viewDidLoad(){
  macICanBuy(budget: 100, closure: { mac in
    print("I can afford a \(mac)")
  })
}

// output: 
// checking budget...
// I can afford a Mcdonalds' Big Mac
// macICanBuy finished execution

在应用程序执行macICanBuy函数之前,它将把传递的参数(预算和关闭信息)加载到手机内存(RAM)中,以便该函数可以使用这些数据。

在应用程序完成执行macICanBuy函数之后,该应用程序不再需要预算和关闭数据,因此它将从内存中删除它们。函数完成执行后,关闭数据无法从内存中移出,因此称为“非转义”关闭。

上引自:

https://fluffy.es/what-is-escaping-closure/

答案 1 :(得分:1)

例如,出于某种原因,ab参数必须为正数。有3种方法可以解决这种情况:

1)您可以在调用add的函数中添加此检查。如果这样做,您将在add调用之前的任何时间重复此代码。由于代码重复,这是一个坏主意; 2)您可以在add方法中添加此检查,并向闭包返回错误。在任何关闭中,即使您不想在这种情况下执行任何代码,也必须处理此错误。因此,这也不是一个好主意。 3)您可以在add方法中添加此检查,并返回一个表明参数正确性的布尔值。如果参数正确,则您将计算结果并按以下代码调用闭包:

func add(a: Int, b: Int, completion: (Int) -> ()) -> Bool {
    guard a > 0, b > 0 else {
      return false
    }

    let addition = a + b
    completion(addition)

    return true
}

if !add(a: someA, b: someB, completion: {sum in print(sum)}) {
  print("Wrong numbers!")
}