閉包

前言

  1. 函數類型做爲變量,能夠接收函數。
  2. 函數類型做爲返回值, 能夠返回函數。
  3. 函數類型做爲參數,這就是閉包。

閉包

  1. 閉包的寫法有不少
    1. 若是是尾隨閉包,能夠把閉包放到小括號的後邊。若是這時候小括號裏邊沒有參數了能夠去掉小括號
    2. 參數類型和返回類型能夠省略
    3. 參數能夠省略用$0,$1表示
    4. 若是是單一的表達式能夠省略return關鍵字
var a = ["2", "3", "1", "0", "4", "6"]

// 1. 普通寫法
var b = a.sorted(by: { (x: String, y: String) -> Bool in
    return x > y
})

//2. 閉包尾隨寫法
var b1 = a.sorted{ (x: String, y: String) -> Bool in
    return x > y
}

//3. 省略參數類型,返回類型寫法
var b2 = a.sorted{ (x, y) in
    return x > y
}

//4. 省略參數寫法
var b3 = a.sorted{
    return $0 > $1
}

//5. 單個表達式省略return寫法
var b4 = a.sorted{$0 > $1}

//6. >號寫法
var b5 = a.sorted(by: >)

print("b = \(b)")


//數組每一個元素映射
let digitNames = [
    0: "Zero", 1: "One", 2: "Two",   3: "Three", 4: "Four",
    5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"
]
let numbers = [16, 58, 510]

let numStr = numbers.map { (number) -> String in
    var num = number
    
    var total = ""
    repeat {
        let temp = num%10
        total = digitNames[temp]! + total
        num /= 10
    }while num > 0
    
    return total
}
print(numStr)
複製代碼
  1. 值的捕獲
    嵌套函數也是一種閉包,閉包能夠捕獲值
func addOneFunc(value:Int) -> () -> Int{
    var total = 0
    func addOne() -> Int{
        total += value
        return total
    }
    return addOne
}

var a = addOneFunc(value: 10)
print(a())
print(a())
print(a())
print(a())
print(a())

var b = addOneFunc(value: 5)
print(b())
print(b())
print(b())
print(b())
print(b())
複製代碼
  1. 逃逸閉包
    1. 逃逸閉包是指函數返回後纔會執行的閉包
    2. 多線程中,函數已經返回,子線程纔開始執行閉包,那這個閉包就須要逃逸
    3. 逃逸閉包入參要寫標註@escaping
    4. 逃逸閉包在調用時候要顯示的寫self
var arr = [() -> Void]()
func escapingClosureFunc(closure: @escaping () -> Void){
    arr.append(closure)
}

func noescapingClosureFunc(closure: () -> Void){
    closure()
}

class SomeClass {
    var x = 10
    func doSomething() {
        escapingClosureFunc {
            self.x = 100
        }
        
        noescapingClosureFunc {
            x = 200
        }
    }
}

var instance = SomeClass()
instance.doSomething()
print(instance.x)

arr.first?()
print(instance.x)
複製代碼
  1. 自動閉包
    1. 自動閉包有延時執行做用
//逃逸閉包能夠延時執行 (變量)
var arr = ["a", "b", "c", "d", "e", "f", "g", "h"]
var removeFirst = {arr.removeFirst()}
print(removeFirst())
//["b", "c", "d", "e", "f", "g", "h"]

//入參
func removeFirstFunc(closure: () -> String){
    print(closure())
}
removeFirstFunc(closure: {arr.removeFirst()})
//["c", "d", "e", "f", "g", "h"]

//自動閉包入參

func removeFirstFuncAuto(closure: @autoclosure () -> String){
    print(closure())
}
removeFirstFuncAuto(closure: arr.removeFirst())
//["d", "e", "f", "g", "h"]


//逃逸自動閉包
var arrClosure: [() -> String] = []
func escapingAutoClosure(closure: @escaping @autoclosure () -> String){
    arrClosure.append(closure)
}

escapingAutoClosure(closure: arr.removeFirst())
escapingAutoClosure(closure: arr.removeFirst())
print(arr)

arrClosure.first?()
arrClosure.first?()
print(arr)
//["f", "g", "h"]
複製代碼
相關文章
相關標籤/搜索