Swift閉包

自包含(什么意思??)的函數(shù)代碼塊
特點:捕獲和存儲上下文的任意常量和變量的引用

有三種閉包:

  • 全局函數(shù):有名字贡避,不捕獲 (閉包性體現(xiàn)在哪里呢)
  • 嵌套函數(shù):有名字砂缩,捕獲封閉函數(shù)域內(nèi)值
  • 閉包表達式:捕獲上下文值得匿名閉包

Swift的閉包主張簡潔入蛆,優(yōu)化:

  • 利用上下文進行類型推斷
  • 隱式返回單表達式閉包吧秕,閉包體只有單個表達式始赎,可以省略return香璃,返回值為表達式的值
  • 參數(shù)名稱縮寫
  • 尾閉包

閉包表達式

是一種利用簡潔語法構(gòu)建內(nèi)聯(lián)閉包的方式这难,語法為:

{ (parameters) -> returnType in
    statements
}

closure不能帶標(biāo)簽(外部參數(shù)名),但是可以用_忽略(社么鬼?)

var closure = { (_ a:Int, b:Int) in
    print(a,b)
}

closure(1,2)

參數(shù)可以為in-out參數(shù)增显,但不能設(shè)定默認值雁佳,可以使用可變參數(shù)(必須放最后一位),假如不放最后一位呢同云?

var closure = { (a:Int..., b:Int) in
    print(a,b)
}

closure(11,11,22)//閉包無法調(diào)用,在定義closure時就該報錯了

具體可以看http://stackoverflow.com/questions/39548852/swift-3-0-closure-expression-what-if-the-variadic-parameters-not-at-the-last-pl (沒體會到意思??堵腹,感覺有點不對)

我的理解:
為什么炸站?因為閉包沒有標(biāo)簽名,編譯器無法知道可變參數(shù)有多長
放在最后一位的話疚顷,別的參數(shù)分配完了后旱易,剩下的都是可變長參數(shù)的了

sorted方法
sorted(by: (String, String) -> Bool);//sorted方法原型

sorted不會對原數(shù)組產(chǎn)生影響,會產(chǎn)生一個新數(shù)組腿堤,sorted函數(shù)參數(shù)接受一個閉包阀坏,全局函數(shù)就是閉包:

let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
func backward(_ s1: String, _ s2: String) -> Bool {
    return s1 > s2
}
var reversedNames = names.sorted(by: backward)

以上是全局函數(shù)的方式傳遞閉包

使用閉包表達式

reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in
    return s1 > s2
})

in關(guān)鍵字來分隔參數(shù)和閉包體,這種方式也叫內(nèi)聯(lián)閉包

上下文類型推斷

閉包參數(shù)類型:根據(jù)數(shù)組內(nèi)元素類型推斷
閉包返回值:sorted已經(jīng)指出
所以閉包可以省略類型

reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )

其實笆檀,像這種內(nèi)聯(lián)閉包表達式作為函數(shù)參數(shù)忌堂,總是可以被推斷類型,所以酗洒,總是可以省略

單表達式閉包隱式返回

閉包體中如果只有一個表達式士修,省略return,會返回這個表達式的值

reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )

參數(shù)名稱縮寫

我們不需要去定義s1和s2樱衷,可以使用名稱縮寫棋嘲,$0,$1矩桂,$2按順序表示參數(shù)表中的參數(shù)沸移,所以參數(shù)表可以去掉,in也要去掉

reversedNames = names.sorted(by: { $0 > $1 } )

運算符方法

終極閉包

reversedNames = names.sorted(by: >)

尾閉包

一個書寫在函數(shù)括號后的閉包表達式,遇見這種格式雹锣,函數(shù)會把閉包作為最后一個參數(shù)調(diào)用
使用條件:閉包表達式作為最后一個參數(shù)時流妻,使用尾閉包增強可讀性。
使用尾閉包時笆制,不用寫出函數(shù)的外部名

func abc(a:Int,closure:()->Void){
}

abc(a:1) {
} //使用尾閉包

abc(a:1,closure: {
})//不使用尾閉包

//當(dāng)參數(shù)只有一個閉包表達式時绅这,括號也可以省略
func abc(closure:()->Void){
}

abc{
}//使用尾閉包

sorted使用尾閉包

reversedNames = names.sorted() { $0 > $1 }
reversedNames = names.sorted { $0 > $1 }
func abc(closure:(Int,String)->Void){
    closure(1,"2")
}

abc { (tuple) in
    print(tuple)//tuple是一個按照參數(shù)表來的元組
}

思考問題:??如何讓閉包調(diào)用時帶有外部參數(shù)名?

Swift中的參數(shù)貌似只能是let型在辆,除非使用in-out证薇,如果想使用var,需要把let類型的常量值給var類型的變量值

值捕獲

閉包可以捕獲被定義上下文中的常量或者變量匆篓。即使這些值的作用域已經(jīng)不在浑度,閉包依然可以使用這些值(延長了值的生命周期)
嵌套函數(shù)可以捕獲外部函數(shù)所有的參數(shù)以及定義的常量和變量

func xyz() -> ()->Void {
    var a = 1
    func abc(){//捕獲a的引用
        a = a + 1
        print(a)
    }
    a = 100 //會影響到abc內(nèi)的值
    abc()
    return abc
}
var m = xyz()//101
m()//102
m()//103

abc捕獲了a的引用,xyz執(zhí)行完畢后鸦概,a還在箩张,因為abc延長了a的生命周期
注意類的循環(huán)引用,以后再做討論

閉包是引用類型

常量值類型窗市,常量引用類型的區(qū)別:

  • 常量值類型的一切都是常量先慷,一旦確定不可更改
  • 常量引用類型的引用不可以改變,但是引用指向的對象是可以改變的

變量值類型咨察,變量引用類型:

  • 都可以變

值類型和引用類型的本質(zhì):給值類型變量起個名字论熙,這個名字就代表這個值,給引用類型變量起個名字摄狱,這個名字僅僅代表這個變量的引用脓诡,不能代表這個變量本身。還需要討論

var a = 1//a是
var b = {
}//

值在傳遞時只能拷貝媒役,引用在傳遞時可以只傳遞引用(其實是地址的拷貝)

逃逸閉包

閉包作為參數(shù)傳遞給函數(shù)祝谚,函數(shù)返回后,才執(zhí)行這個閉包酣衷,我們稱這個閉包為逃逸閉包交惯。或者說作為函數(shù)參數(shù)的閉包可以在函數(shù)體外被調(diào)用叫做逃逸閉包鸥诽。逃逸閉包必須指定@escaping
如何讓閉包逃逸商玫?把閉包保存在全局變量中,函數(shù)執(zhí)行完畢后再調(diào)用閉包

var outcl:(()->Void)? //注意閉包類型的括號牡借,沒有括號就是返回值為Void?可選了

func taoyibibao(incl:@escaping ()->Void) {
    outcl = incl;
}

taoyibibao {
}

outcl!()//調(diào)用必須被初始化拳昌,所以`taoyibibao`需要先執(zhí)行

逃逸閉包必須顯式調(diào)用self

var outTaoyiCl:(()->Void)?

func taoyi(inTaoyiCl:@escaping ()->Void) {
    outTaoyiCl = inTaoyiCl
}

func butaoyi(inBuTaoyiCl:()->Void) {
    inBuTaoyiCl()
}

class A {
    var x:Int = 1
    func doSomeThing() {
        taoyi {
            self.x = 2 //逃逸出去的閉包必須顯式使用self來捕獲當(dāng)前類實例
        }
        butaoyi {
            x = 2 //非逃逸閉包則可以省略self
        }
    }
}

自動閉包

使用條件:沒有參數(shù),返回閉包體中表達式的值

func abc(xyz:()->String) {
    print(xyz())
}

abc {"呵呵"}

改為自動閉包

func abc(xyz:@autoclosure ()->String) {
    print(xyz())
}

abc(xyz: "呵呵");//聲明成自動閉包后钠龙,參數(shù)變?yōu)橐粋€值(值或者返回值的表達式或者函數(shù)等)炬藤,這個值會被自動轉(zhuǎn)換成閉包

自動閉包就是調(diào)用形式變了御铃,本來形參為閉包表達式,加了@autoclosure沈矿,就可以只傳一個值或者表達式或者返回這種類型的函數(shù)調(diào)用上真。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市羹膳,隨后出現(xiàn)的幾起案子睡互,更是在濱河造成了極大的恐慌,老刑警劉巖陵像,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件就珠,死亡現(xiàn)場離奇詭異,居然都是意外死亡醒颖,警方通過查閱死者的電腦和手機妻怎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泞歉,“玉大人逼侦,你說我怎么就攤上這事⊙遥” “怎么了榛丢?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長沟优。 經(jīng)常有香客問我涕滋,道長,這世上最難降的妖魔是什么挠阁? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮溯饵,結(jié)果婚禮上侵俗,老公的妹妹穿的比我還像新娘。我一直安慰自己丰刊,他們只是感情好隘谣,可當(dāng)我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著啄巧,像睡著了一般寻歧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上秩仆,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天码泛,我揣著相機與錄音,去河邊找鬼澄耍。 笑死噪珊,一個胖子當(dāng)著我的面吹牛晌缘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播痢站,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼磷箕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了阵难?” 一聲冷哼從身側(cè)響起岳枷,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎呜叫,沒想到半個月后空繁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡怀偷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年家厌,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片椎工。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡饭于,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出维蒙,到底是詐尸還是另有隱情掰吕,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布颅痊,位于F島的核電站殖熟,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏斑响。R本人自食惡果不足惜菱属,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望舰罚。 院中可真熱鬧纽门,春花似錦、人聲如沸营罢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽饲漾。三九已至蝙搔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間考传,已是汗流浹背吃型。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留伙菊,地道東北人败玉。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓敌土,卻偏偏與公主長得像,于是被迫代替她去往敵國和親运翼。 傳聞我的和親對象是個殘疾皇子返干,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 閉包是自包含的函數(shù)代碼塊,可以在代碼中被傳遞和使用血淌。Swift 中的閉包與 C 和 Objective-C 中的代...
    窮人家的孩紙閱讀 1,708評論 1 5
  • 閉包是功能性自包含模塊矩欠,可以在代碼中被傳遞和使用。Swift中的閉包與 C 和 Objective-C中的 blo...
    AirZilong閱讀 348評論 0 2
  • 閉包可以從定義它們的上下文中捕獲和存儲對任何常量和變量的引用悠夯。 這被稱為關(guān)閉這些常量和變量癌淮。 Swift處理所有的...
    Joker_King閱讀 593評論 0 2
  • Swift 中的閉包是自包含的函數(shù)代碼塊,可以在代碼中被傳遞和使用沦补。類似于OC中的Block以及其他函數(shù)的匿名函數(shù)...
    喬克_叔叔閱讀 522評論 1 3
  • 閉包是自包含的代碼塊乳蓄,可以在代碼中被傳遞和使用。Swift中的閉包與C和Objective-C中代碼塊(block...
    Raaaaamsey閱讀 847評論 0 2