逃逸闭包
- 当闭包作为一个实际参数传递给一个函数的时候,并且它会在函数返回之后调用,我们就说这个闭包逃逸了。当你声明一个接受闭包作为形式参数函数时,你可以在形式参数前写 @escaping 来明确闭包是允许逃逸的。
- 闭包可以逃逸的一种方法是被储存在定义于函数外的变量里。比如说,很多函数接受闭包实际参数来作为启动异步任务的回调。函数在启动任务后返回,但是闭包要直到任务完成一一闭包需要逃逸,以便于稍后调用。
- 让闭包 @escaping 意味着你必须在闭包中显式地引用 self
自动闭包
- 自动闭包是一种自动创建的用来把作为实际参数传递给函数的表达式打包的闭包。它不接受任何实际的参数,并且当它被调用时,它会返回内部打包的表达式的值。
- 这个语法的好处在于通过写普通表达式代替显式闭包而使你省略包围函数形式参数的括号。
- 自动闭包允许你延迟处理,因此闭包内部的代码直到你调用它的时候才会运行。对于有副作用或者占用资源的代码来说很有用,因为它可以允许你控制代码何时才能进行求值。
var customersInLine = ["Chris", "Alex", "Barry", "Eva", "Daniella"]
print(customersInLine.count)
let customerProvider = { customersInLine.remove(at: 0) }
print(customersInLine.count)
print("Now serving \(customerProvider()) !")
print(customersInLine.count)
执行结果如下:
5
5
Now serving Chris !
4
- 当你传一个闭包作为实际参数到函数的时候,你会得到与延迟处理相同的行为。
var customersInLine = ["Chris", "Alex", "Barry", "Eva", "Daniella"]
print(customersInLine.count)
func serve(customer customerProvider:() -> String) {
print("Now serving \(customerProvider()) !")
}
serve(customer: { customersInLine.remove(at: 0) })
执行结果如下:
5
Now serving Chris !
- 通过 @autoclosure 标志标记它的形式参数使用了自动闭包。现在你可以调用函数就像它接收了一个 String 实际参数而不是闭包。实际参数自动地转换为闭包,因为 customerProvider 形式参数的类型被标记为 @autoclosure 标记。
var customersInLine = ["Chris", "Alex", "Barry", "Eva", "Daniella"]
print(customersInLine.count)
func serve(customer customerProvider: @autoclosure () -> String) {
print("Now serving \(customerProvider()) !")
}
serve(customer: customersInLine.remove(at: 0))
执行结果如下:
5
Now serving Chris !
自动➕逃逸
- 如果你想要自动闭包允许逃逸,就同时使用 @autoclosure 和 @escaping 标志。
var customersInLine = ["Barry", "Daniella"]
var customerProviders:[() -> String] = []
func collecCustomerProviders(_ customerProvider : @autoclosure @escaping () -> String ) {
customerProviders.append(customerProvider)
}
collecCustomerProviders(customersInLine.remove(at: 0))
collecCustomerProviders(customersInLine.remove(at: 0))
print("Collected \(customerProviders.count) closures.")
for customerProvider in customerProviders {
print("Now serving \(customerProvider()) !")
}
执行结果如下:
Collected 2 closures.
Now serving Barry !
Now serving Daniella !
网友评论