block內(nèi)修改變量的值

block內(nèi)修改變量的值

本部分分析基于下面代碼。

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        int age = 10;
        Block block = ^ {
            // age = 20; // 無法修改
            NSLog(@"%d",age);
        };
        block();
    }
    return 0;
}

默認情況下block不能修改外部的局部變量。通過之前對源碼的分析可以知道。

age是在main函數(shù)內(nèi)部聲明的,說明age的內(nèi)存存在于main函數(shù)的棧空間內(nèi)部,但是block內(nèi)部的代碼在__main_block_func_0函數(shù)內(nèi)部。__main_block_func_0函數(shù)內(nèi)部無法訪問age變量的內(nèi)存空間,兩個函數(shù)的??臻g不一樣,__main_block_func_0內(nèi)部拿到的ageblock結(jié)構(gòu)體內(nèi)部的age,因此無法在__main_block_func_0函數(shù)內(nèi)部去修改main函數(shù)內(nèi)部的變量。

方式一:age使用static修飾。

前文提到過static修飾的age變量傳遞到block內(nèi)部的是指針,在__main_block_func_0函數(shù)內(nèi)部就可以拿到age變量的內(nèi)存地址,因此就可以在block內(nèi)部修改age的值。

方式二:__block

__block用于解決block內(nèi)部不能修改auto變量值的問題,__block不能修飾靜態(tài)變量(static) 和全局變量

__block int age = 10;

編譯器會將__block修飾的變量包裝成一個對象,查看其底層c++源碼。

上述源碼中可以發(fā)現(xiàn)

首先被__block修飾的age變量聲明變?yōu)槊麨?code>age的__Block_byref_age_0結(jié)構(gòu)體,也就是說加上__block修飾的話捕獲到的block內(nèi)的變量為__Block_byref_age_0類型的結(jié)構(gòu)體。

通過下圖查看__Block_byref_age_0結(jié)構(gòu)體內(nèi)存儲哪些元素。

__isa指針__Block_byref_age_0中也有isa指針也就是說__Block_byref_age_0本質(zhì)也一個對象。

__forwarding__forwarding__Block_byref_age_0結(jié)構(gòu)體類型的,并且__forwarding存儲的值為(__Block_byref_age_0 *)&age,即結(jié)構(gòu)體自己的內(nèi)存地址。

__flags :0

__sizesizeof(__Block_byref_age_0)__Block_byref_age_0所占用的內(nèi)存空間。

age :真正存儲變量的地方,這里存儲局部變量10。

接著將__Block_byref_age_0結(jié)構(gòu)體age存入__main_block_impl_0結(jié)構(gòu)體中,并賦值給__Block_byref_age_0 *age;

之后調(diào)用block,首先取出__main_block_impl_0中的age,通過age結(jié)構(gòu)體拿到__forwarding指針,上面提到過__forwarding中保存的就是__Block_byref_age_0結(jié)構(gòu)體本身,這里也就是age(__Block_byref_age_0),在通過__forwarding拿到結(jié)構(gòu)體中的age(10)變量并修改其值。

后續(xù)NSLog中使用age時也通過同樣的方式獲取age的值。

2020面試刷題與技術(shù)儲備專區(qū)

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

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

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