用__block修饰变量,会发生什么?

425 阅读1分钟

我们在block中使用到auto变量的时候,一般会在其前面加上一个__weak,比如说:

__block int age = 10;
CTBlock block = ^{
		age = 20;
};
block();

通过编译成c++代码,我们可以看到其底层实现:

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

首先看整个block的数据结构:

struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  __Block_byref_age_0 *age; // by ref
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_age_0 *_age, int flags=0) : age(_age->__forwarding) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

其中,age 是一个指向__main_block_desc_0结构体的指针,我们看下它的数据结构:

struct __Block_byref_age_0 {
  void *__isa;
__Block_byref_age_0 *__forwarding;
 int __flags;
 int __size;
 int age;
};

那就很明显了,原本只是一个基本数据类型int,被block捕获之后,给生成了一个结构体类型,并且在里面存储了age的值。