Block __block修飾符

如果block需要捕獲某個變量后進行賦值,這個變量在聲明時需要使用 __block修飾。

void testBlock2() {
    
    __block int num = 3;
    void(^block)(int) = ^(int i){
        num = 4;
        NSLog(@"i * num = %d", num * i);
    };
    num = 5;
    block(2); 
}

clang -rewrite-objc main.m,查看main.cpp文件

void testBlock2() {

    __attribute__((__blocks__(byref))) __Block_byref_num_0 num = 
                        {(void*)0,(__Block_byref_num_0 *)&num, 0, sizeof(__Block_byref_num_0), 3};
    void(*block)(int) = ((void (*)(int))&__testBlock2_block_impl_0((void *)__testBlock2_block_func_0, 
                        &__testBlock2_block_desc_0_DATA, (__Block_byref_num_0 *)&num, 570425344));
    (num.__forwarding->num) = 5;
    ((void (*)(__block_impl *, int))((__block_impl *)block)->FuncPtr)((__block_impl *)block, 2);
}

__block修飾的局部變量基本類型變成了 __Block_byref_num_0 結(jié)構(gòu)體

struct __Block_byref_num_0 {
  void *__isa;
__Block_byref_num_0 *__forwarding;
 int __flags;
 int __size;
 int num;
};

struct __testBlock2_block_impl_0 {
  struct __block_impl impl;
  struct __testBlock2_block_desc_0* Desc;
  __Block_byref_num_0 *num; // by ref
  __testBlock2_block_impl_0(void *fp, struct __testBlock2_block_desc_0 *desc, 
                            __Block_byref_num_0 *_num, int flags=0) : num(_num->__forwarding) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

此時 _num->__forwarding 指向 __Block_byref_num_0 *num。
(num.__forwarding->num) = 5 這是再給num對象的num屬性賦值。
__block修飾后,局部變量會被轉(zhuǎn)化一個對象,局部變量的值將會是這個對象一個成員變量,而截獲的是這個對象。
與沒有__block修飾區(qū)分開,沒有__block修飾時,是截獲的值。

void testBlock2() {
    
    __block int num = 3;
    void(^block)(int) = ^(int i){
        NSLog(@"i * num = %d", num * i);
    };
    num = 5;
    block(2); // i * num = 10
}

void testBlock3() {
    
    int num = 3;
    void(^block)(int) = ^(int i){
        NSLog(@"i * num = %d", num * i);
    };
    num = 5;
    block(2); // i * num = 6
}

如果截獲的變量,不賦值,僅僅是使用,不需要使用__block

void testBlock4() {
    
    //不需要__block修飾,沒有對array賦值,而僅僅是使用。
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:0];
    void(^block)(int) = ^(int i){
        [array addObject:@(i)];
    };
    block(2);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

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

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