如果函数本身可以返回值,那么为什么需要调用非转义闭包来返回值? 考虑以下示例
func add(a: Int, b: Int, completion: (Int) -> ()) {
let addition = a + b
completion(addition)
}
答案 0 :(得分:2)
用于关闭的常见用例是:
异步调用;网络。
函数存储为变量;思考动作和提供的回调。
在调度队列上调度任务。
如果有一个过程需要一些时间才能完成工作并退还结果。在这些情况下,关闭是最佳选择。
非逃逸关闭
非转义的闭包具有非常清晰的生命周期,因此已成为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函数之后,该应用程序不再需要预算和关闭数据,因此它将从内存中删除它们。函数完成执行后,关闭数据无法从内存中移出,因此称为“非转义”关闭。
上引自:
答案 1 :(得分:1)
例如,出于某种原因,a
和b
参数必须为正数。有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!")
}