Swift_閉包

Swift_閉包


點擊查看源碼git

閉包優化

//閉包優化
func testClosures() {
    //函數作參數 排序
    let names = ["XuBaoAiChiYu", "1045214799", "iOS", "Swift", "OC"]
    func backwards(_ s1: String, _ s2: String) -> Bool {
        return s1 > s2
    }
    var reversed = names.sorted(by: backwards)
    print(reversed)
    
    //閉包排序
    reversed = names.sorted(by: { (s1: String, s2: String) -> Bool in
        return s1 > s2
    })
    print(reversed)
    
    //能夠寫爲一行
    reversed = names.sorted( by: { (s1: String, s2: String) -> Bool in return s1 > s2 } )
    print(reversed)
    
    //閉包能夠自動判斷參數類型和返回屬性
    reversed = names.sorted( by: { s1, s2 in return s1 > s2 } )
    print(reversed)
    
    //當只有一行時,可省略return寫法。
    reversed = names.sorted( by: { s1, s2 in s1 > s2 } )
    print(reversed)
    
    //閉包中的參數可以使用$去得到 第一個參數爲$0 第二個爲$1
    reversed = names.sorted( by: { $0 > $1 } )
    print(reversed)
    
    //當閉包中只有兩個參數 作比較操做時 只須要寫入符號
    reversed = names.sorted(by: >)
    print("\(reversed)")
    
    /*  print
     
     ["iOS", "XuBaoAiChiYu", "Swift", "OC", "1045214799"]
     ["iOS", "XuBaoAiChiYu", "Swift", "OC", "1045214799"]
     ["iOS", "XuBaoAiChiYu", "Swift", "OC", "1045214799"]
     ["iOS", "XuBaoAiChiYu", "Swift", "OC", "1045214799"]
     ["iOS", "XuBaoAiChiYu", "Swift", "OC", "1045214799"]
     ["iOS", "XuBaoAiChiYu", "Swift", "OC", "1045214799"]
     ["iOS", "XuBaoAiChiYu", "Swift", "OC", "1045214799"]
     
     */
}

尾隨閉包

//尾隨閉包
func testTrailingClosures() {
    
    let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
    
    //若是函數須要一個閉包做爲參數,且這個參數是最後一個參數.
    //尾隨閉包能夠放在函數參數列表外,也就是括號外
    var reversed = names.sorted() { $0 > $1 }
    print("\(reversed)")
    
    //若是一個閉包表達式做爲一個惟一的參數,你又正在使用尾隨閉包,能夠省略()
    reversed = names.sorted { $0 > $1 }
    print("\(reversed)")
    
    /*  print
     
     ["Ewa", "Daniella", "Chris", "Barry", "Alex"]
     ["Ewa", "Daniella", "Chris", "Barry", "Alex"]
     
     */
}

捕獲值

//捕獲值
func testCapturingValues() {
    /*
     閉包能夠根據環境上下文捕獲到定義的常量和變量。閉包能夠引用和修改這些捕獲到的常量和變量,
     就算在原來的範圍內定義爲常量或者變量已經再也不存在(很牛逼)。
     在Swift中閉包的最簡單形式是嵌套函數。
     */
    func makeIncrementer(forIncrement amount: Int) -> () -> Int {
        var runningTotal = 0
        func incrementer() -> Int {
            runningTotal += amount
            return runningTotal
        }
        return incrementer
    }
    
    let incrementByTen = makeIncrementer(forIncrement: 10)
    print("\(incrementByTen())")
    print("\(incrementByTen())")
    print("\(incrementByTen())")
    
    let incrementBySeven = makeIncrementer(forIncrement: 7)
    print("\(incrementBySeven())")
    print("\(incrementByTen())")
    
    //閉包是引用類型
    let alsoIncrementByTen = incrementByTen
    print(alsoIncrementByTen())
    
    /*  print
     
     10
     20
     30
     7
     40
     50
     
     */
}

避免內存泄露

//避免內存泄露
var completionHandlers: [() -> Void] = []
func someFunctionWithNoescapeClosure(_ closure: () -> Void) {
    closure()
//    completionHandlers.append(closure) //會報錯 closure沒法被保存
}

func someFunctionWithEscapingClosure(_ completionHandler: @escaping () -> Void) {
    completionHandler()
    completionHandlers.append(completionHandler)
}

class SomeClass {
    var x = 10
    func doSomething() {
        //內存溢出
        someFunctionWithEscapingClosure { self.x = 100 }
        someFunctionWithNoescapeClosure { x = 200 }
    }
}
func testNonescapingClosures() {
    //@noescape 保留環問題 閉包中布應使用self 避免內存泄露
    let instance = SomeClass()
    instance.doSomething()
    print(instance.x)
    
    completionHandlers.first?()
    print(instance.x)
    
    /*  print
     
     200
     100
     
     */
}
相關文章
相關標籤/搜索