Block对自动变量的截获以及__block

block是如何截获自动变量的

小demo

int main(int argc, const char * argv[]) {
   
    
    int val = 2;
    void (^blk)(void) = ^{
   
        NSLog(@"in block, val = %d", val);
    };

    val = 10;
    
    blk();
    NSLog(@"not in block, val = %d", val);
    return 0;
}

在这里插入图片描述
转换成c++之后的底层代码

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

         NSLog((NSString *)&__NSConstantStringImpl__var_folders_yy_rtbfwwy91hj81qhy92yrypy40000gn_T_main_25ce61_mi_0, val);
     }

 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)};
 
 int val = 2;
 void (*blk)(void) = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, val));

 val = 10;

 ((void (*)(__block_impl *))((__block_impl *)blk)->FuncPtr)((__block_impl *)blk);
 NSLog((NSString *)&__NSConstantStringImpl__var_folders_yy_rtbfwwy91hj81qhy92yrypy40000gn_T_main_25ce61_mi_1, val);

一个普通Block的小demo 由此进行对比

    void (^blk)(void) = ^{
   
        NSLog(@"i am an common Block");
    };
struct __main_block_impl_0 {
   
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) {
   
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
   

        NSLog((NSString *)&__NSConstantStringImpl__var_folders_yy_rtbfwwy91hj81qhy92yrypy40000gn_T_main_e7a4eb_mi_0);
    }

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)};
int main(int argc, const char * argv[]) {
   

    void (*blk)(void) = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));
	((void (*)(__block_impl *))((__block_impl *)blk)->FuncPtr)((__block_impl *)blk);
}

block的内部结构与没有截获时候的区别

 struct __main_block_impl_0 {
   
   struct __block_impl impl;
   struct __main_block_desc_0* Desc;
   int val;
   __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _val, int flags=0) : val(_val) {
   
     impl.isa = &_NSConcreteStackBlock;
     impl.Flags = flags;
     impl.FuncPtr = fp;
     Desc = desc;
   }
 };
 //没有截获
 struct __main_block_impl_0 {
   
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) {
   
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

根据转换之后的代码 block把block块表达式当中的自动变量作为一个成员变量加入到了自己的结构体中

并且

  1. 结构体内声明的成员变量类型和局部变量类型完全相同
  2. block块表达式中没有出现的局部变量不会添加
  3. 截获的val只是截获了该局部变量的值

该结构体的实例化函数和调用与没有截获时候的区别

   __main_block_impl_0(void *fp, 
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

waxuuuu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值