Swift应用案例 2.闭包入门到精通
??本文主要介紹Swift的閉包的使用并與OC的Block做比較。學(xué)習(xí)Swift是繞不過閉包的,因為無論是全局函數(shù)還是嵌套函數(shù)都是閉包的一種,本文主要介紹閉包表達式。
1.閉包表達式的使用
// 1.定義一個閉包let myClosure = {(s1: String, s2:String) -> Boolinself.count = 10;print("------");return s1 > s2}print(count!);// 2.調(diào)用閉包let result = myClosure("Chris","Alex")print("result = \(result)")print("count = \(count!)")日志
result = true count = 10總結(jié) :1.和oc的block的聲明和調(diào)用在形式上是極其類似的,不過閉包可以直接修改局部變量和全局變量的值,而block需要__block 關(guān)鍵字。
// 3.Tralling 閉包(尾隨)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 strings = numbers.map {( number) -> String invar number = numbervar output = ""while number > 0 {output = digitNames[number % 10]! + outputnumber /= 10}return output}print(strings);日志
["OneSix", "FiveEight", "FiveOneZero"]2.Trailing 閉包
??函數(shù)的表現(xiàn)形式:(void)函數(shù)名(參數(shù))。如果一個函數(shù)的最后一個參數(shù)是一個閉包,允許你寫在參數(shù)所在哪個()外面。
(void)函數(shù)名(參數(shù)) {
};
如果只有閉包一個參數(shù),括號可以省略。變成:
(void)函數(shù)名 {
};
當閉包里的代碼很多的時候,這樣寫可以增加代碼的可讀性,多用于調(diào)用系統(tǒng)的函數(shù)。
??舉例之前先介紹一下map函數(shù),map屬于Array的一個函數(shù),調(diào)用這個函數(shù)需要傳入一個閉包,返回一個新數(shù)組。Array里的每一個元素都會調(diào)用這個閉包,生成一個新對象,加入到新數(shù)組中。相當于 自動執(zhí)行了for in和addobject兩個方法,很實用。
使用Trailing 閉包之前
let strings = numbers.map({( number) -> String invar number = numbervar output = ""while number > 0 {output = digitNames[number % 10]! + outputnumber /= 10}return output})使用Trailing 閉包之后
let strings = numbers.map{( number) -> String invar number = numbervar output = ""while number > 0 {output = digitNames[number % 10]! + outputnumber /= 10}return output}??就一個參數(shù)不明顯, 但是參數(shù)多了還是很有用的。因為閉包里的代碼一般有很多,會導(dǎo)致包含參數(shù)的()距離太遠。
3. 捕獲: 解決嵌套函數(shù)的循環(huán)引用
func makeIncrementor(forIncrement amount: Int) -> () -> Int {var runningTotal = 0func incrementor() -> Int {// 只能捕獲包含他的函數(shù)體內(nèi)的變量或常量的值,建立一個副本,相當于深拷貝// 新變量runningTotal += amountreturn runningTotal}print(" ----- runningTotal = \(runningTotal)")return incrementor}let incrementByTen = makeIncrementor(forIncrement: 10)print("incrementor = \(incrementByTen())")print("incrementor = \(incrementByTen())")print("incrementor = \(incrementByTen())")打印
----- runningTotal = 0 incrementor = 10 incrementor = 20 incrementor = 30總結(jié):incrementor里的runningTotal就是對:incrementor外的runningTotal的捕獲。捕獲有以下幾個特點。
(1)捕獲會生成一個新變量,和捕獲變量的值相等,但內(nèi)存不同,是引用類型,相當于OC中的深拷貝,新變量變化和捕獲的變量沒有任何關(guān)系了。因為incrementor外的runningTotal的值一直沒有改變。
(2)嵌套函數(shù)對新變量是強引用,只要嵌套函數(shù)還在,新變量就在,因為incrementor的返回值是一直增加的。
(3)如果不這樣為什么會造成循環(huán)引用,incrementor對makeIncrementor變量runningTotal的引用就是對makeIncrementor的引用。運用捕獲,就只是對runningTotal值的拷貝,不引用。
4.閉包傳值
??在OC中我們用block最多的地方就是傳值了,同樣閉包也是。不過運用block和閉包傳值最好是當對象只有一個狀態(tài)的時候,如果對象狀態(tài)很多最好用代理。
CycleScrollView 往CycleScrollViewViewController進行傳值
接收閉包傳過來的值
import UIKitclass CycleScrollViewViewController: UIViewController {var cycleScrollView : CycleScrollView?override func viewDidLoad() {super.viewDidLoad()createUI()}func createUI() {self.automaticallyAdjustsScrollViewInsets = false;cycleScrollView = CycleScrollView.init(frame: CGRect(x:0,y:64,width:ScreenWidth,height:ScreenHeight - 64))// 閉包傳值cycleScrollView?.didSelectItemClosure = {(index : Int) -> Void inprint("您點擊了第 \(index) 個")}self.view.addSubview(cycleScrollView!)}override func didReceiveMemoryWarning() {super.didReceiveMemoryWarning()} }??如果傳值的例子有點沒看懂,可以去下載我的DEMO,里面有詳細的代碼。閉包還是很厲害的,不需要我們進行任何操作就解決了循環(huán)引用問題,不像block還得對變量進行弱引用。本文部分內(nèi)容是對Swift閉包詳解的整理。
轉(zhuǎn)載于:https://www.cnblogs.com/doujiangyoutiao/p/6626310.html
總結(jié)
以上是生活随笔為你收集整理的Swift应用案例 2.闭包入门到精通的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PC端 java 开发蓝牙所遇到的问题
- 下一篇: Tomcat源代码解析系列