block 之 block引用局部變量

前言

這一篇主要著重對(duì)__block關(guān)鍵字的理解

例子

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        int a = 10;
        void (^helloBlock)(void) = ^(){
            printf("%d\n",a);
        };
        a = 11;
        helloBlock();
 
    }
    return 0;
}

上面那個(gè)例子運(yùn)行后的結(jié)果是10。我們可以編譯看一下block里面匿名函數(shù)的實(shí)現(xiàn):

static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
  int a = __cself->a; // bound by copy

            printf("%d\n",a);
}

bound by copy這里的注釋表示,block對(duì)它引用的局部變量做了只讀拷貝,也就是說block引用的是局部變量的副本。所以在執(zhí)行block語(yǔ)法后,即使改寫block中使用的局部變量的值也不會(huì)影響block執(zhí)行時(shí)局部變量的值。
那怎么樣才能修改a的值呢?答案就是__block

__block

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        __block int a = 10;
        void (^helloBlock)(void) = ^(){
            printf("%d\n",a);
        };
        a = 11;
        helloBlock();
 
    }
    return 0;
}

引入__block關(guān)鍵字后,運(yùn)行結(jié)果是11,我們?cè)倬幾g看看block里面匿名函數(shù)的實(shí)現(xiàn)


static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
  __Block_byref_a_0 *a = __cself->a; // bound by ref

            printf("%d\n",(a->__forwarding->a));
}

struct __Block_byref_a_0 {
  void *__isa;
__Block_byref_a_0 *__forwarding;
 int __flags;
 int __size;
 int a;
};

我們看到局部變量a變成一個(gè)構(gòu)造體對(duì)象,而不再是一個(gè)整形變量,結(jié)構(gòu)體里包含它原來的整形變量。bound by ref這個(gè)注釋也表明此時(shí)已變成引用傳遞

小小總結(jié)

block可以引用局部變量,但是不能修改它,不然就是編譯錯(cuò)誤,如果想修改它,可以加上__block關(guān)鍵字。但是可以改變?nèi)肿兞俊㈧o態(tài)變量、全局靜態(tài)變量。

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

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