一.閉包創建語法
{(parameters) -> return type in
statements
}
例子 :
let names = ["Chris","Alex","Ewa","Barry","Daniella"]
func backward( s1: String,_ s2: String) ->Bool {
return s1 > s2
}
var reversedNames = names.sort(backward)
上面的是傳入普通函數,我們也可以傳入一個閉包
reversedNames = names.sort({ (s1:String, s2: String) -> Boolin
return s1 > s2
})
二.閉包類型推斷
閉包被當做參數傳入方法時,閉包的參數類型和返回值有可能被推斷出來,這時我們可以省略參數類型和返回值, 因此上面的 例子也可以寫成:
reversedNames =names.sort({ s1, s2 inreturn s1 > s2 } )
reversedNames = names.sort({ s1, s2 in s1 > s2 } )
二.簡短的參數名
如果我們知道函數的類型,既我們可以從函數裏知道,傳入函數的閉包需要幾個參數每個參數的類型是什麼,我們 可以省略閉 包的參數列表,in 關鍵詞也可省略,因爲此時閉包裏全爲可執行語句。通過$0,$1,$2......的方式來引用傳 入的參數
reversedNames =names.sorted(by: { $0 > $1 } )
三. Trailing Closures
reversedNames = names.sort { $0 > $1 }
四.捕獲值
閉包可以捕獲在閉包外面內容常量和變量,閉包可以引用和改變這些常量和變量。閉包的捕獲使這些變量和常量不 被釋放。
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementer() -> Int {
runningTotal += amount
return runningTotal
}
return incrementer
}
let incrementByTen = makeIncrementer(forIncrement: 10)
incrementByTen()
// returns a value of 10
incrementByTen()
// returns a value of 20
incrementByTen()
五.閉包是引用類型
當您將一個函數或一個閉包賦給一個常量或一個變量時,您實際上是在設置常量或變量來引用函數或閉包的函數。
六.閉包的Non-Escaping和 Escaping
Non-Escaping Closures
注意閉包沒有從這函數體內逃逸。當函數結束,傳入的閉包從函數體出來時,沒有添加額外的引用。閉包的引用計數在函數開始執行和結束是相同的
Escaping Closures
Escaping and Non-Escaping in Swift 3
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"
在逃逸閉包裏必須用 self 來引用外圍的內容,而非逃逸閉包則不用。
七.自動閉包
一個自動閉包是一個沒有參數,包裹一個表達式的閉包。當我們調用這個閉包它返回這個表達式的值。
print(customersInLine.count)
// Prints "5"
let customerProvider = { "ddd";}
print(customersInLine.count)
// Prints "5"
print("Now serving \(customerProvider())!")
// Prints "Now serving Chris!"
print(customersInLine.count)
// Prints "4"