OC Block本質分析:

block的一些概念什麼的就不說了,主要記錄一下,block是怎麼實現的。函數

在main.m中寫了一個blockspa

 

用  clang -rewrite-objc main.m   會生成一個main.cpp 文件,是C++代碼,其實就是用到了C++的結構體,熟悉一些C++的結構體語法就能看懂了。(這個cpp文件中代碼炒雞多,只要看關於Block的就好了,以下圖)指針

 

首先分析建立Block代碼:

這個block結構體就是咱們平時用的block 的本質,它由 兩個結構體變量一個結構體構造方法組成內存

 

 

main函數中 紅色框是block的建立.源碼

拆開看就是調用了block結構體的構造方法: __main_block_impl_0()  it

,這個構造方法須要傳入3個參數:1.void *fp      2.desc(計算保存block的大小)     3.flags = 0(flags 系統默認傳0)變量

對於 void *fp(fp是能夠指向任何類型的指針變量)。原理

咱們看源碼,它是傳入了(void *)__main_block_func_0   爲何這麼寫呢?由於函數名能夠表明一個函數在內存中的首地址,void *fp 能夠指向任何類型,固然也能夠指向函數類型, 又函數名能夠表明首地址,因此這裏直接傳函數名就能夠,其實不寫前面的強制轉換(void *) 也是能夠的。語法

而且這個fp 被賦值給 block結構體中的,成員結構體__block_impl 中的成員 void *FuncPtr方法

下面咱們拆開看這個紅色框的代碼:

到此就完成了block的建立。

 

 

接着看Block的調用:

去掉強制轉換的部分:

代碼的意思是:經過指針變量找到那個建立的block(結構體) 取block(結構體) 裏面的impl結構體 的成員 FuncPtr 所指向的方法(即:咱們寫在block塊中的方法)  並執行方法。

 

就是調用下面這個方法,執行 printf("哈哈")。  其中 __cself 指向 Block值,Block做爲參數進行了傳遞。

static void __main_block_func_0( struct __main_block_impl_0 *__cself ) {

        printf("哈哈");

}

 

 

 

Block 捕獲自動變量(自動變量:沒有任何顯示修飾符的局部變量)

 

clang 後的代碼:

能夠看到block結構體中多了一個 int a;看上圖,能夠知道block將這個a存儲在int a變量中了

 

 

執行block分析:

__cself->a  取出block結構體中的a變量值  ,而後打印輸出。

 

如今明白了block捕獲自動變量的原理了吧!

相關文章
相關標籤/搜索