Closure 的定義網上也比較多比較全,下面所寫不會具體介紹語法,只做簡單歸納、實例闡述。
一、歸納屬性閉包
1.常見的完整的屬性閉包寫法
//定義
var fun1 = {
(a:Int,b:Int) -> Int in
return a+b
}
//調用
print(fun1(1,1))
2.定義后立即調用
var fun2 = {
(a:Int,b:Int) -> Int in
return a+b
}(1,2)
3.閉包的類型實際上是一種函數類型,根據接收變量的類型來自動推到閉包對應的類型
var fun3:(Int,Int)->Int = {
(a,b) in
return a+b
}
print(fun3(1,3))
4.閉包的類型實際上是一種函數類型,根據實參的類型和返回值來自動推到閉包對應的類型
var fun4 = {
a,b in
return a+b
}(1,4)
5.省略return語句
var fun4 = {
a,b in
a+b
}(1,4)
6.省略形參名和in關鍵字(可以是用$0,$1...來應用對應參數)
var fun5:(Int,Int)->Int = {
$0 + $1
}
print(fun5(1,5))
var fun6 = {
$0 + $1
}(1,5)
二、Closure 在函數中的應用
1.尾隨閉包
定義:閉包表達式可以作為函數的參數傳遞,如果閉包表達式很長,就會影響程序的可讀性。尾隨閉包是一個書寫在函數括號之后的閉包表達式,函數支持將其作為最后一個參數調用。
func showPlus(opr:String,fun:(Int,Int)->Int){
switch (opr) {
case "+" :
print("1 + 1 = \(fun(1,1))")
default:
print("1 - 1 = \(fun(1,1))")
}
}
//正常調用
showPlus(opr: "+", fun: {(a:Int,b:Int)->Int in return a+b})
//尾隨閉包
showPlus(opr: "-"){(a:Int,b:Int)->Int in return a-b}
2.捕獲值
閉包可以訪問本體之外的變量或常量,函數和閉包都是引用類型
func makeIncrementer(forIncrement amount: Int)->(Void)-> Int{
var runningTotal = 0
func incrementer()->Int{
runningTotal += amount
return runningTotal
}
return incrementer
}
let funMI = makeIncrementer(forIncrement: 10)
funMI()
funMI()
funMI()
3.非逃逸閉包
定義:閉包closureHandler作為一個參數傳遞給一個函數的時候,funcClosure函數返回了才執行閉包,我們就說閉包逃逸了。當我們用@noescope修飾閉包時,該閉包的生命周期不能超出該函數,同時不能被中的其他閉包捕獲。假如給closureHandler加上@noescope修飾就會報錯
var closureArray: [() -> Void] = []
func funcClosure(closureHandler: () -> Void) {
closureArray.append(closureHandler)
}
5.自動閉包
將表達式包裝成閉包,為了不會浪費資源選擇性求值,調用方式不變,參數寫法不同
func verifyidentity(action1:Bool, action2:Bool){
}
func isAction1()->Bool{
print("isAction1 is action")
return true
}
func isAction2()->Bool{
print("isAction2 is action")
return true
}
verifyidentity(action1: isAction1(), action2:isAction2())
三、回調實例
class A{
//可以用關鍵字typealias定義一個公共的Closure,不需要理解,就下面這種定義就行了
typealias Block = (wu:NSString,dan:NSString)->()
var block:Block
init() {
self.block = {
name,dan in
print(name)
}
print("函數已經結束")
}
}
class B{
var a:A?
func action(){
self.a?.block(wu: "wudanfeng",dan: "10")
}
}
var a = A()
var b = B()
b.a = a
b.action()