block --- 來(lái)自于我的理解和使用

block的使用與創(chuàng)建

block object-c 中的匿名函數(shù)

最常見(jiàn)的疑問(wèn) 截取變量

image.png

途中 我們可以看到 age 的值打印的是10 而不是下面修改的18, 就是讓很多人有了部分的疑問(wèn)。
在我看到這段代碼的時(shí)候,查閱了部分的做資料,了解到了部分底層編譯所執(zhí)行的內(nèi)容


image.png

Block語(yǔ)法轉(zhuǎn)換成C函數(shù)后,Block語(yǔ)法表達(dá)式中用到的自動(dòng)變量會(huì)被作為成員變量追加到了__main_block_impl_0結(jié)構(gòu)體中。
而此結(jié)構(gòu)體中的成員變量類型與自動(dòng)變量類型完全相同,但僅限于Block語(yǔ)法中使用到的自動(dòng)變量。
因此,所謂“截獲自動(dòng)變量值”意味著執(zhí)行Block語(yǔ)法時(shí),Block語(yǔ)法表達(dá)式所使用的自動(dòng)變量值被保存到Block的結(jié)構(gòu)體實(shí)例中。
這個(gè)時(shí)候的age, 在底層就是copy了一份,生成了新的對(duì)象,和之前的age 是互不影響的。

__block說(shuō)明符

在Block中修改截獲的自動(dòng)變量值有兩種方法。
1.使用靜態(tài)變量,靜態(tài)全局變量,全局變量
從Block語(yǔ)法轉(zhuǎn)換成的C語(yǔ)言函數(shù)中訪問(wèn)靜態(tài)全局變量 / 全局變量并沒(méi)有任何改變,可直接使用。
但是靜態(tài)變量卻是用靜態(tài)變量的指針來(lái)對(duì)其進(jìn)行訪問(wèn),這是超出作用域使用變量的最簡(jiǎn)單方法。
2.使用 __block 修飾符

image.png

在這里,age 值是被修改的,那么,為什么使用__block就能修改里面的值呢,我們繼續(xù)往下走:
通過(guò)clang 內(nèi)部:
···
attribute((blocks(byref))) __Block_byref_val_0 val = {(void*)0,(__Block_byref_val_0 *)&val, 0, sizeof(__Block_byref_val_0), 10};
···
__block 增加了 __Block_byref_val_0結(jié)構(gòu)體類型的自動(dòng)變量,即棧上生成的__Block_byref_val_0結(jié)構(gòu)體實(shí)例
image.png

剛剛在Block中向靜態(tài)變量賦值時(shí),使用了指向該靜態(tài)變量的指針。
而向__block變量賦值時(shí),Block的__main_block_impl_0結(jié)構(gòu)體實(shí)例會(huì)持有指向__block變量的_Block_byref_val_0 結(jié)構(gòu)體實(shí)例的指針。
也就是Block的__main_block_impl_0結(jié)構(gòu)體實(shí)例會(huì)持有一個(gè)指針,指向__block修飾的變量所轉(zhuǎn)換的__Block_byref_val_0結(jié)構(gòu)體實(shí)例。
而__Block_byref_val_0結(jié)構(gòu)體通過(guò)成員變量__forwarding指針訪問(wèn)成員變量val

另外,為了能在多個(gè)Block中使用__block變量,__block變量的__Block_byref_val_0結(jié)構(gòu)體并不在Block用__main_block_impl_0結(jié)構(gòu)體中。
Block是通過(guò)__Block_byref_val_0結(jié)構(gòu)體實(shí)例的指針來(lái)訪問(wèn)。

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

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