Block底層實現系列 一 基礎篇

2021-08-20 19:16:21 字數 3418 閱讀 8934

通過這篇博文, 你可以了解到不訪問/訪問外部變數, 不修改外部變數的block被轉換到c++後的實現方法.

void callblock(void (^myblock)(void))

void testblock();

callblock(testblock);

}int main(int argc, const

char * argv)

return

0;}

使用命令列

$ clang -rewrite-objc main.m

被轉換到如下**(只挑選出block的轉換部分)

struct __block_impl ;
void callblock(void (*myblock)(void))
struct

__testblock_block_impl_0

};

static

void __testblock_block_func_0(struct __testblock_block_impl_0 *__cself)

static

struct __testblock_block_desc_0 __testblock_block_desc_0_data = ;

void testblock()
int main(int argc, const

char * argv)

return

0;}

**行數增加了很多, 我們一點點的說.

先看最熟悉的

static

void __testblock_block_func_0(struct __testblock_block_impl_0 *__cself)

我們寫的block內部執行語句, 最後會轉換到這個方法內部. 在看看這個方法是被誰呼叫的.搜尋一下會發現, __testblock_block_func_0只有在testblock() 方法中出現過, 我們來看看這個方法

void testblock()
這段**各種轉換的有點亂了, 如果簡化一下

void testblock()
__testblock_block_func_0 被傳到__testblock_block_impl_0的內部了. 來看看__testblock_block_impl_0

struct

__testblock_block_impl_0

};

impl.funcptr = fp;說明我們的__testblock_block_func_0被傳入到impl->funcptr的變數中.

回到void testblock()中, 再看第二行callblock(testblock);

void testblock()
例項化了乙個__testblock_block_impl_0型別變數, 並傳遞到了callblock方法中.

void callblock(void (*myblock)(void))
這段**簡化一下後變成如下

void callblock(void (*myblock)(void))
funcptr(myblock)上文說到, 我們的__testblock_block_func_0被傳入到impl->funcptr的變數中. 這一行就呼叫__testblock_block_func_0方法, 同時將__testblock_block_impl_0的例項變數myblock傳入方法中.

到此就完成的方法的呼叫.

void callblock(void (^myblock)(void))

void testblock();

callblock(testblock);

}int main(int argc, const

char * argv)

轉換之後的**:

struct __block_impl ;
void callblock(void (*myblock)(void))
struct

__testblock_block_impl_0

};

static

void __testblock_block_func_0(struct __testblock_block_impl_0 *__cself)

static

struct __testblock_block_desc_0 __testblock_block_desc_0_data = ;

void testblock()
int main(int argc, const

char * argv)

先看下這段**

void testblock()
我們訪問的外部變數aaa = 333被傳入到__testblock_block_impl_0中. 再看__testblock_block_impl_0

struct

__testblock_block_impl_0

};

對比不訪問外部變數的block現在的 __testblock_block_impl_0 結構體剛好多了乙個成員變數aaa. 說明我們訪問的外部變數在轉換後, 會變成__testblock_block_impl_0例項的成員變數.

呼叫的過程與不訪問外部變數的步驟基本一直. 這裡不在贅述,

static

void __testblock_block_func_0(struct __testblock_block_impl_0 *__cself)

這個方法與不訪問外部變數方法不太一樣, 多了一行int aaa = __cself->aaa;

上文我們提到aaa被傳入到__testblock_block_impl_0結構體例項testblock中, 通過callblock方法傳遞給了__testblock_block_func_0, 這裡的 __cself指的就是testblock例項.

Block底層實現

步驟一 建立乙個控制台應用,在main中新增塊的測試 import int main int argc,const char ar testblock return 0 步驟二 開啟終端,定位到main.m檔案目錄,錄入xcode命令 xcrun sdk iphoneos clang arch ar...

block的底層實現原理

block就是指向結構體的指標,編譯器會將block的內部 生成對應的函式,利用這個指標就可以呼叫這個函式.普通的區域性變數是值傳遞,用 block static 或者是全域性變數就是位址傳遞 block的記憶體預設是存放在棧裡面的,他不會對所引用的物件進行操作 如果對block做一次copy操作b...

iOS OC語言 Block底層實現原理

先來簡單介紹一下block block是什麼?蘋果推薦的型別,效率高,在執行中儲存 用來封裝和儲存 有點像函式,block可以在任何時候執行。block和函式的相似性 1 可以儲存 2 有返回值 3 有形參 4 呼叫方式一樣。定義乙個簡單的block 我們再給a賦值為20,此時列印出來a 的值還是1...