Swift 閉包

閉包是特殊的函數(shù)

Swift 中,閉包其實(shí)是一個(gè)特殊的函數(shù),匿名函數(shù)

var block = {
    
    print("3")
}

print(block)

輸出

(Function)

閉包語(yǔ)法

{ (參數(shù)) -> 返回值類型 in
  閉包實(shí)現(xiàn)
  return 返回值
}

簡(jiǎn)寫:

// 單行閉包 省略 return
let block1 = { (parm: Int) -> Int in parm + 1}
print(block1(3))

// 省略返回值類型 (單行多行閉包都可以)
let block2 = { (parm: Int) in parm + 1}

let block3 = { (parm: Int) in
    return parm + 1
}
print(block3(2))

// 省略參數(shù)、返回值 in,直接用 $0 $1 來(lái)訪問(wèn)
let block4 = {
    
    return $0 + 1
}

print(block4(5))

// 如果參數(shù)的類型已知(根據(jù)函數(shù)判斷),可以省略參數(shù)類型以及括號(hào)
func tmpFunc(block: (Int) -> (Void)) {
    
    let a = 10
    
    block(a)
}
tmpFunc { p0 in
    print("\(p0 + 1)")
}

簡(jiǎn)寫規(guī)則:

  • 如果是單行閉包,可以省略 return

  • 如果已知返回值類型(根據(jù)函數(shù)類型推斷),可以省略 返回值類型

  • 如果已知參數(shù)類型,可以省略 參數(shù)類型參數(shù)的括號(hào)()

  • 如果用 $0 $1... 來(lái)訪問(wèn)參數(shù),可以省略 參數(shù)int

簡(jiǎn)單來(lái)說(shuō),除了 大括號(hào){}函數(shù)體 之外,滿足特定條件的話就都可以省略

尾隨閉包

尾隨閉包是特殊的閉包,即當(dāng)在函數(shù)的最后一個(gè)參數(shù)是閉包的時(shí)候,那么這個(gè)閉包是尾隨閉包

func theFunc(parm: Int, block: (Int) -> (Void)) {
    
}

上述函數(shù)的 block 是一個(gè)尾隨閉包

特性:

  • 在調(diào)用尾隨閉包的時(shí)候,可以將閉包寫到參數(shù)括號(hào)外面:
theFunc(parm: 3) { (par) -> (Void) in
    
}

這樣可以增強(qiáng)可讀性

  • 當(dāng)函數(shù)只有一個(gè)閉包作為參數(shù)的時(shí)候,調(diào)用的時(shí)候可以省略 括號(hào)()
func theFunc2(block: (Int) -> (Void)) {
    
}

theFunc2 { (par) -> (Void) in
    
}

逃逸閉包

閉包作為參數(shù)傳遞給函數(shù)的時(shí)候,其作用域?yàn)楹瘮?shù)內(nèi)部,即當(dāng)函數(shù)返回的時(shí)候,該閉包就釋放了,如果想在函數(shù)返回之后還能執(zhí)行,需要使用逃逸閉包。

如果不顯式指明閉包是逃逸閉包,則 默認(rèn)是非逃逸(non-escaping) 閉包。顯式指明為逃逸閉包需要在參數(shù)中增加 @escaping 關(guān)鍵字:

func func0(block: @escaping () -> ()) {

}

函數(shù) func0 接受的 block 是一個(gè)逃逸閉包,作用域不僅限于函數(shù)內(nèi)

通常用于需要保存閉包的場(chǎng)景:

var blocks:[() -> ()] = [() -> ()]()

func saveBlock(block: @escaping () -> ()) {
    
    blocks.append(block)
    
}

// 保存 block
saveBlock {
    
    print("hello")
    
}

// 在 saveBlock 方法返回后才執(zhí)行到這兒
let block = blocks[0]
block()

輸出:

hello

上述代碼和輸出表明,逃逸閉包的作用域不僅限于函數(shù)中。

自動(dòng)閉包

自動(dòng)閉包能將是普通閉包的一種,主要的區(qū)別的在聲明的時(shí)候不需要聲明參數(shù),在調(diào)用的時(shí)候傳入?yún)?shù),并且由 Swift 自動(dòng)將參數(shù)封裝成帶參數(shù)的閉包

這一種閉包需要在閉包前加上關(guān)鍵字 @autoclosure,如下:

func tmpFunc(isSuc: Bool, block:  @autoclosure ()->(Bool)) {
    
    if (isSuc) {
        block()
    }
}

該函數(shù)的 block 參數(shù)就是一個(gè)自動(dòng)閉包,在傳參的時(shí)候僅需要傳入一個(gè) 返回值為 Bool 的表達(dá)式即可,如下:

tmpFunc(isSuc: false, block: 2>3)

思考:為什么需要自動(dòng)閉包?(自動(dòng)閉包的使用場(chǎng)景)

主要是為了節(jié)省開銷,實(shí)際上,在 tmpFunc 的聲明時(shí)候,我們聲明其第二個(gè)參數(shù)是一個(gè) Bool 類型而無(wú)需是一個(gè)閉包也能很好地工作。但是假如后面的表達(dá)式需要耗費(fèi)大量的時(shí)間去計(jì)算的話,且第一個(gè)參數(shù)為 false,就會(huì)造成不必要的開銷,因?yàn)槲覀兏緹o(wú)需計(jì)算第二個(gè)參數(shù)的值。

可以看出使用閉包可以省去不必要的提前計(jì)算。

func tmpFunc(isSuc: Bool, block:  @autoclosure ()->(Bool)) {
    
    if (isSuc) {
        if (block()) {
            print("a")
        }
    }
}

func tmpFunc2(isSuc: Bool, block:  Bool) {
    
    if (isSuc) {
        if (block) {
            print("b")
        }
    }
}

tmpFunc(isSuc: false, block: 2>3 && 2>3 && 2>3 && 2>3 && 2>3 && 2>3)
tmpFunc2(isSuc: false, block: 2>3 && 2>3 && 2>3 && 2>3 && 2>3 && 2>3)

tmpFunc 僅在 isSuctrue 的時(shí)候會(huì)調(diào)用 2>3 && 2>3 && 2>3 && 2>3 && 2>3 && 2>3 這個(gè)復(fù)雜表達(dá)式,而 tmpFunc2 無(wú)論 isSuc 為何值都會(huì)調(diào)用那個(gè)復(fù)雜的表達(dá)式,造成了不必要的復(fù)雜計(jì)算。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 感覺有點(diǎn)難懂,可以參考http://www.itdecent.cn/p/49e7a29a2698 閉包是自包含的...
    CDLOG閱讀 707評(píng)論 0 0
  • 閉包是自包含的函數(shù)代碼塊,可以在代碼中被傳遞和使用。Swift 中的閉包與 C 和 Objective-C 中的代...
    窮人家的孩紙閱讀 1,813評(píng)論 1 5
  • 閉包可以從定義它們的上下文中捕獲和存儲(chǔ)對(duì)任何常量和變量的引用。 這被稱為關(guān)閉這些常量和變量。 Swift處理所有的...
    Joker_King閱讀 642評(píng)論 0 2
  • Swift 中的閉包是自包含的函數(shù)代碼塊,可以在代碼中被傳遞和使用。類似于OC中的Block以及其他函數(shù)的匿名函數(shù)...
    喬克_叔叔閱讀 558評(píng)論 1 3
  • 致讀者:這是一個(gè)集現(xiàn)實(shí)與奇幻,幽默與諷刺于一體的故事。既接地氣,又發(fā)人深省。不好看給我寄刀片! 1 劉月娥快四十的...
    奇奇漫悅讀閱讀 10,761評(píng)論 70 114

友情鏈接更多精彩內(nèi)容