點擊查看源碼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 */ }