iOS block幾種類型,為什么使用copy修飾

block快的存儲(chǔ)位置(block入口的地址)可能存放在3個(gè)地方:代碼區(qū)(全局區(qū))、堆區(qū)、棧區(qū)(ARC情況下回自動(dòng)拷貝到堆區(qū)、因此ARC下只有兩個(gè)地方:代碼區(qū)和堆區(qū))
有三種常見(jiàn)的類型:
①<NSGlobalBlock: 0x102cef0b8>
存儲(chǔ)在程序的代碼段,全局區(qū);NSGlobalBlock:不會(huì)訪問(wèn)任何外部變量,比如:

    void(^blockA)(void) = ^{
        NSLog(@"just a block");
    };
    NSLog(@"%@", blockA);

②<NSMallocBlock: 0x60000025b120>
存儲(chǔ)在堆上。當(dāng)blcok的引用計(jì)數(shù)為0時(shí)會(huì)被銷毀,比如:

    int value = 10;
    void(^blockB)(void) = ^{
        NSLog(@"just a block === %d",value);
    };
    NSLog(@"%@", blockB);

③<NSStackBlock: 0x7ffeecf0fad0>
存儲(chǔ)在棧上,NSStackBlock:在block內(nèi)部引用外部變量,除了函數(shù)作用域會(huì)被銷毀,引用導(dǎo)致奔潰,所以需要拷貝到堆上,比如:

    // 強(qiáng)行在ARC上將一個(gè)block創(chuàng)建在棧上
    void(^__weak blockC)(void) = ^{
        NSLog(@"just a block === %d",value);
    };
    NSLog(@"%@", blockC);

//注意:在arc情況下,沒(méi)有NSStackBlock這個(gè)類型,如果有系統(tǒng)自動(dòng)copy成為NSMallocBlock,同時(shí)會(huì)拷貝代碼內(nèi)部變量如:

    int base = 2;
    base += 2;
    long (^sums)(int,int)  = ^ long (int a,int b){
        return base + a + b;
    };
    base ++;
    NSLog(@"%ld",sums(1,2));
    //輸出的結(jié)果為 7 arc下提前拷貝base

需要特別注意的是,在ARC下,很多都已經(jīng)自動(dòng)幫我們Copy成了MallocBlock了,由于Block是默認(rèn)建立在棧上,所以如果離開(kāi)方法作用域就會(huì)釋放,如果要在外部調(diào)用,需要用copy指向它,這樣就拷貝到了堆區(qū),strong不具有拷貝功能

?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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