Swift的閉包和OC的Block里值的捕獲的區(qū)別

看一段OC代碼

    NSInteger i = 1;
    void(^block)(void) = ^{
        NSLog(@"block %ld:", i);
    };
    i += 1;
    NSLog(@"out1 %ld:", i);
    block();
    NSLog(@"out2 %ld:", i);

打印


oc.png

在OC里,編譯器走到第三行的時(shí)候,實(shí)際上已經(jīng)對(duì)i進(jìn)行了拷貝,可以理解成

NSInteger iCopy = i

所以block里的值和外面的值是不會(huì)互相影響的。
如果想要里外一致,則需要通過添加 __block關(guān)鍵字,block里使用的變量不管是基本數(shù)據(jù)列行還是類,都會(huì)自動(dòng)封裝成一個(gè)對(duì)象(結(jié)構(gòu)體),這個(gè)對(duì)象擁有isa指針和forwarding指針,forwarding指針指向的是自己,在ARC下block里有用到外部局部變量則會(huì)自動(dòng)copy到堆,在棧區(qū)的forwarding指針就指向到堆里的isa(堆里的forwarding還是指向自己),這就打通了內(nèi)外,這里不詳細(xì)討論此關(guān)鍵字以及循環(huán)引用相關(guān)。


看一段Swift代碼

        var i = 1
        let closure = {
            print("closure \(i)")
        }
        i += 1
        print("out1 \(i)")
        closure()
        print("out 2 \(i)")

代碼和OC一毛一樣,打印的結(jié)果是


swift

swift指的捕獲是在執(zhí)行的時(shí)候再捕獲,當(dāng)代碼執(zhí)行到 closure(),對(duì)值進(jìn)行捕獲,i的值是2,所以打印閉包里的i等于2

修改值
在OC里修改值基本數(shù)據(jù)類型__block, OC-Obj類型__weak。
在Swift里,看如下代碼

 var i = 1
        let closure = {
            i += 1
            print("closure \(i)")
        }
        i += 1
        print("out1 \(i)")
        closure()
        print("out 2 \(i)")

在閉包里多了一行 i += 1 編譯,沒有警告,運(yùn)行結(jié)果如下

image.png

也就是說,在swift里,閉包就像是oc給外部變量默認(rèn)添加了block或者__weak


Swift里實(shí)現(xiàn)和OC一樣的值捕獲,這種實(shí)現(xiàn)在Swift里叫捕獲列表,capturing list
看如下代碼

var i = 1
        let closure = {
            [i] in
            print("closure \(i)")
        }
        i += 1
        print("out1 \(i)")
        closure()
        print("out 2 \(i)")

閉包內(nèi)部多了一行[i] in 語(yǔ)法為中括號(hào)[]里面添加捕獲的變量,然后用in 分割上下分。打印結(jié)果為

image.png

類似于剛開始的OC代碼,Swift內(nèi)部,類似執(zhí)行了這樣的一行代碼

let iCopy = i

最后

大家都說Swift里的閉包和OC里的block一樣,在值的捕獲這里是有很大的不一樣的。

最后編輯于
?著作權(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)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,211評(píng)論 4 61
  • 時(shí)針指向8點(diǎn)。時(shí)間差不多了,走,我們?nèi)ズ染屏T。老陳叫上小米,向門口走去。在院子裏,老陳打電話給Z,在哪兒,去喝酒罷...
    應(yīng)蘇閱讀 210評(píng)論 0 0
  • 1. 選擇dev分支。 然后pull dev分支。 然后merge into 自己開發(fā)的分支。 然后在merge ...
    smile刺客閱讀 6,097評(píng)論 0 0
  • My code: My test result: 這次作業(yè)比較簡(jiǎn)單,但如果按照他所說的, one pass就做出結(jié)...
    Richardo92閱讀 373評(píng)論 0 1
  • 英語(yǔ)思維 1)西方人表達(dá)直接,中國(guó)人講究委婉、含蓄。(英語(yǔ)思維:重點(diǎn)突出,) 2)西方人講究秩序,遵守規(guī)則,中國(guó)人...
    一枚冰兒閱讀 779評(píng)論 2 3

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