Block本質(zhì)(底層結(jié)構(gòu)&變量捕獲)

block本質(zhì)上也是一個(gè)OC對(duì)象,它內(nèi)部也有一個(gè)isa指針,block是封裝了函數(shù)調(diào)用以及函數(shù)調(diào)用環(huán)境的OC對(duì)象。

Block的底層結(jié)構(gòu)

如下圖所示:


block底層結(jié)構(gòu).png

先在項(xiàng)目中定義一個(gè)block,然后執(zhí)行block,通過(guò)命令行clang -rewrite-objc main.m,將OC代碼轉(zhuǎn)化為c++代碼,看一下block的底層結(jié)構(gòu)。

block底層結(jié)構(gòu)C++對(duì)照

現(xiàn)在通過(guò)右側(cè)的OC代碼,對(duì)照看一下c++源碼。

void(^block)(void) = ^{
  NSLog(@"Hello, World!");
};
block();

//定義block
 void(*block)(void) = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));
//執(zhí)行block內(nèi)部代碼
 ((void (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block);

block就相當(dāng)于__main_block_impl_0;執(zhí)行block,就相當(dāng)于__block_impl->FuncPtr,找到block中封裝的函數(shù)FuncPtr,然后執(zhí)行。

Block的變量捕獲

為了保證block內(nèi)部能夠正常訪(fǎng)問(wèn)內(nèi)部的變量,block有個(gè)變量捕獲機(jī)制


block變量捕獲.png

auto變量存放在動(dòng)態(tài)存儲(chǔ)區(qū),隨著生命周期的結(jié)束而立即釋放。只有函數(shù)的局部變量才能定義為auto類(lèi)型。
static變量存放在靜態(tài)存儲(chǔ)區(qū),在程序整個(gè)運(yùn)行期間都不釋放。在函數(shù)內(nèi)定義的靜態(tài)變量為靜態(tài)局部變量,在函數(shù)外定義的靜態(tài)變量為靜態(tài)全局變量。

以下分別為Block中引用auto類(lèi)型局部變量,static局部變量以及全局變量,通過(guò)OC代碼編譯成c++源碼的對(duì)照


block變量捕獲C++對(duì)照.png
運(yùn)行結(jié)果:
 Block[1635:48861] age is 10, height is 20, weight is 110

上圖可以看出age和height變量都被捕獲到block中,age是值捕獲,height是值捕獲,全部變量weight沒(méi)有被捕獲。

對(duì)象類(lèi)型的auto變量

當(dāng)block內(nèi)部訪(fǎng)問(wèn)了對(duì)象類(lèi)型的auto變量時(shí)

  • 如果block是在棧上,將不會(huì)對(duì)auto變量產(chǎn)生強(qiáng)引用

  • 如果block被拷貝到堆上
    會(huì)調(diào)用block內(nèi)部的copy函數(shù)
    copy函數(shù)內(nèi)部會(huì)調(diào)用_Block_object_assign函數(shù)
    _Block_object_assign函數(shù)會(huì)根據(jù)auto變量的修飾符(__strong、__weak、__unsafe_unretained)做出相應(yīng)的操作,形成強(qiáng)引用(retain)或者弱引用

  • 如果block從堆上移除
    會(huì)調(diào)用block內(nèi)部的dispose函數(shù)
    dispose函數(shù)內(nèi)部會(huì)調(diào)用_Block_object_dispose函數(shù)
    _Block_object_dispose函數(shù)會(huì)自動(dòng)釋放引用的auto變量(release)

?著作權(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)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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