block 實現原理詳解(一)

對於大多數人來說,block內部究竟是怎樣實現的呢?咱們能夠藉助clang將其編譯成爲c++的代碼,就能夠看出,block究竟是什麼東西,c++

先來看這樣一個問題,函數

<!-- lang: cpp -->
        int age = 10;
    void (^block)() = ^{
        NSLog(@"%d",age);
    };
    age  = 30;
    block();//10

以及下面的這一段代碼指針

<!-- lang: cpp -->
        __block int age = 10;
    void (^block)() = ^{
        NSLog(@"%d",age);
    };
    age  = 30;
    block();//30

你會發現這兩個結果是不一樣的, 第一個輸出10,第二個輸出的是30code

要想知道這裏面幹了些什麼!須要咱們將其編譯成爲C++代碼,看下里面到底搞了些什麼? 使用終端,轉到mian.m文件下,使用以下代碼 clang -rewrite-objc main.m 將其編譯生成 main.cpp文件 這時候,咱們打開mian.cpp便知 在文件的最底下main函數中編譯器

<!-- lang: cpp -->
int main(int argc, const char * argv[])

{博客

/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 

    __attribute__((__blocks__(byref))) __Block_byref_age_0 age = {(void*)0,(__Block_byref_age_0 *)&age, 0, sizeof(__Block_byref_age_0), 10};
    void (*block)() = (void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, (__Block_byref_age_0 *)&age, 570425344);
    (age.__forwarding->age) = 30;
    ((void (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block);

}
return 0;

}it

block內部是調用了一個結構體中的函數: static struct __main_block_desc_0 { size_t reserved; size_t Block_size; void (copy)(struct __main_block_impl_0, struct __main_block_impl_0*); void (dispose)(struct __main_block_impl_0); }編譯

而後通過分析該c++文件咱們知道 block其實是: 指向結構體的指針 編譯器會將block的內部代碼生成對應的函數基礎

而在mian.m中,調用普通的int變量時,傳過來的age實際上是一個值傳遞,而__block則是引用傳遞! 因此,纔是如上的結果!變量

這是對block的一個基礎認識,再接下來的一篇博客中,我講介紹一下mrc和arc使用block的區別 但願能對讀者有用!

相關文章
相關標籤/搜索