Block實現原理

2021-07-24 20:16:54 字數 2812 閱讀 9640

#import

int main(int argc, const

char * argv) ;

i = 3;

myblock ();

}return

0;}

執行結果:i的值是:2為什麼是2 不是3呢?帶著這個疑問我們往下看

編譯main.m檔案,1.開啟終端,2.找到工程檔案,3.找到main.m檔案所在的位置,4.clang -rewrite-objc main.m重新編譯會生成乙個main.cpp的檔案。這個檔案相當大滑倒檔案底部找到如下**

int main(int argc, const char * argv) 

return 0;

}

由上面的**我們看到block被轉化為了__main_block_impl_0的結構體例項

struct

__main_block_impl_0

};

desc :描述 block 的結構體變數;

i:引數

__main_block_impl_0 :結構體的建構函式,初始化結構體變數 impl、desc;

impl:__block_impl 是 block 實現的結構體

struct __block_impl ;
isa:指向例項物件,說明 block 本身也是 objective-c 物件;

flags:按位承載 block 的附加資訊;

reserved :保留變數;

funcptr:函式指標,指向 block 要執行的函式,即 __main_block_func_0;

static

void __main_block_func_0

// __main_block_func_0 是 block 要最終要執行的函式**

static

void __main_block_func_0(struct __main_block_impl_0 *__cself)

__main_block_impl_0型別的引數__cself在__main_block_func_0內部copy了乙份i,我們列印的實際上是新複製的這乙份,所以block內部的i和外部的i不是同乙份,不論外部i怎麼變化,對block內部都沒有影響,也就解釋了為什麼列印結果是2不是3

static

struct __main_block_desc_0 __main_block_desc_0_data = ;

reserved :結構體資訊保留字段

block_size :結構體大小

此處已定義了乙個該結構體型別的變數 __main_block_desc_0_data

#import

int main(int argc, const

char * argv) ;

i = 3;

myblock ();

}return

0;}

執行結果:i的值是:3這又是為什麼呢?咱們繼續往下看

clang -rewrite-objc main.m 開啟main.cpp 找到如下**

int main(int argc, const char * argv) ;

void (*myblock)() = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_data, (__block_byref_i_0 *)&i, 570425344));

(i.__forwarding->i) = 3;

((void (*)(__block_impl *))((__block_impl *)myblock)->funcptr)((__block_impl *)myblock);

}return 0;

}

我們發現只是在引數i前面加__block,i的定義變複雜了很多,i 是__block_byref_i_0型別的結構體

struct __block_byref_i_0 ;
__isa :指向例項物件,表明i是oc的物件,不再是基本資料型別

__forwarding:指向自己的指標

void (*myblock)() = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_data, (__block_byref_i_0 *)&i, 570425344));
main_block_impl_0 中引用的是 block_byref_i_0 的結構體指標

struct

__main_block_impl_0

};

從__main_block_impl_0結構體看到:i(_i->__forwarding),i的值是通過__forwarding指標取到的, (i.__forwarding->i) = 3;

修改的也是__forwarding指向的block_byref_i_0結構體中的i,所以列印結果為3

在寫的過程中參考了如下文章,謝謝文章作者

block的實現

Block中 block實現原理

三.block中 block實現原理 我們繼續研究一下 block實現原理。1.普通非物件的變數 先來看看普通變數的情況。import int main int argc,const char ar myblock return 0 把上述 用clang轉換成原始碼。struct block byr...

block的實現原理

main.m import block實際上是 指向結構體的指標 編譯器會將block的內部 生成對應的函式 void test1 block func 0 void test1 a 20 block 10 void test2 a 20 block 20 void test3 a 20 block...

block實現原理詳解

對於大多數人來講,block內部到底是怎樣實現的呢?我們可以借助clang將其編譯成為c 的 就可以看出,block到底是什麼東西,先來看這樣乙個問題,int age 10 void block age 30 block 10 以及下面的這一段 block int age 10 void block...