Block

定義

void (^名稱)(參數(shù)) = ^{
};

使用

名稱();

參考示例

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSLog(@"Hello, World!");
        
        int num = 1;
        void (^block)(void) = ^{
            NSLog(@"打印了 num = %d",num);
            NSLog(@"這個是 block");
        };
        
        block();
        
    }
    return 0;
}

原理解析

首先我們將上面的代碼生成 cpp 文件看一下上面的代碼會將我們的內(nèi)容編譯成什么樣子

編譯命令:

xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main.cpp

最終生成內(nèi)容如下

int main(int argc, const char * argv[]) {
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 

        NSLog((NSString *)&__NSConstantStringImpl__var_folders_dv_nb1mrprn3kj3cnk3tts4918w0000gn_T_main_f590b1_mi_0);

        int num = 1;
        void (*block)(void) = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, num));

        ((void (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block);

    }
    return 0;
}

關鍵結構體有下面內(nèi)容

struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  int num;
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _num, int flags=0) : num(_num) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};
struct __block_impl {
  void *isa;
  int Flags;
  int Reserved;
  void *FuncPtr;
};
static struct __main_block_desc_0 {
  size_t reserved;
  size_t Block_size;
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
  int num = __cself->num; // bound by copy

            NSLog((NSString *)&__NSConstantStringImpl__var_folders_dv_nb1mrprn3kj3cnk3tts4918w0000gn_T_main_f590b1_mi_1,num);
            NSLog((NSString *)&__NSConstantStringImpl__var_folders_dv_nb1mrprn3kj3cnk3tts4918w0000gn_T_main_f590b1_mi_2);
        }

可以發(fā)現(xiàn)我們最后的 block 定義其實是生成了一個結構體,并通過結構體的構造函數(shù)傳遞了三個參數(shù)。

&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, num)

參數(shù)一:__main_block_func_0 則是我們實際執(zhí)行的代碼
參數(shù)二: __main_block_desc_0_DATA 是 block 的信息記錄,Block_size 記錄了 block 的大小。
參數(shù)三:num 則是我們訪問的外部變量,賦值給了 block 內(nèi)的變量 num

而且通過觀察 __main_block_impl_0,我們可以發(fā)現(xiàn)此處也是生成了 isa 指針的,所以我們可以確認我們的 block 是一個對象。并且在構造函數(shù)中將傳入的代碼執(zhí)行地址傳遞給了 impl 的 funcPtr, 在下面我們調用 block() 的時候實際也就是調用的 (impl->funcPtr)(num)

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

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