")
} //函数执行完,不会打印"hello"
completionHandlers.first?() //打印"hello"
如果逃逸闭包访问的是类里面的成员,必须带上self来访问;如果访问的是全局的变量,则和非逃逸闭包一样。我的理解是,既然闭包逃逸了,则出了函数的作用域,则如果需要访问类里面的成员也找不到地址,因为函数已经被销毁,所以,需要带上类的地址self指针。
var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
completionHandlers.append(completionHandler)
}
func someFunctionWithNonescapingClosure(closure: () -> Void) {
closure()
}
class SomeClass {
var x = 10
func doSomething() {
someFunctionWithEscapingClosure { self.x = 100 }
someFunctionWithNonescapingClosure { x = 200 }
}
}
let instance = SomeClass()
instance.doSomething()
print(instance.x)
// Prints "200"
completionHandlers.first?()
print(instance.x)
// Prints "100"
7.自动闭包(Autoclosures)
An autoclosure is a closure that is automatically created to wrap an expression that’s being passed as an argument to a function. It doesn’t take any arguments, and when it’s called, it returns the value of the expression that’s wrapped inside of it. This syntactic convenience lets you omit braces around a function’s parameter by writing a normal expression instead of an explicit closure.
自动闭包,我理解是,没有参数,函数体只有返回值,没有多余的其他变量,举个例子:
let printStr = { "hello" }
print(printStr()) //hello
var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
let customerProvider = { customersInLine.remove(at: 0) }
print("Now serving \(customerProvider())!") // Prints "Now serving Chris!"
注意:要保证自动闭包里面代码能正确执行,比如,在执行customerProvider()之前把数组清空,那么执行customerProvider()会报错,代码如下:
customersInLine.removeAll()
customerProvider() //fatal error: Index out of range
自动闭包作为函数参数,不写"{}",直接写返回值:
1 var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
2
3 //一般闭包
4 func serve(customer customerProvider: () -> String) {
5 print("Now serving \(customerProvider())!")
6 }
7 serve(customer: {customersInLine.remove(at: 0)}) //Now serving Chris!
8
9 //自动闭包
10 func serve(customer customerProvider: @autoclosure () -> String) {
11 print("Now serving \(customerProvider())!")
12 }
13 serve(customer: customersInLine.remove(at: 0)) //Now serving Chris!
逃逸的自动闭包:
var customersInLine = ["Barry", "Daniella"]
// customersInLine is ["Barry", "Daniella"]
var customerProviders: [() -> String] = []
func collectCustomerProviders(_ customerProvider: @autoclosure @escaping () -> String) {
customerProviders.append(customerProvider)
}
collectCustomerProviders(customersInLine.remove(at: 0))
collectCustomerProviders(customersInLine.remove(at: 0))
print("Collected \(customerProviders.count) closures.")
// Prints "Collected 2 closures."
for customerProvider in customerProviders {
print("Now serving \(customerProvider())!")
}
// Prints "Now serving Barry!"
// Prints "Now serving Daniella!"
8.总结
swift的闭包比Object-C的block功能强大很多,更简洁,更高效。而且,很多集合类型都集成了闭包,比如:map,flatMap等等。这些闭包的功能都很强大,也为swift添加了不少便利性。
原文链接:http://www.jianshu.com/p/a618d5fd9881