__block

127 阅读1分钟

__block

///__block 只能对auto变量进行修饰
__block int a = 10得原理是什么?
///1:runtime 内部会生存一个__block对象
///2:__block对象会持有 int a这个变量
///3:修改得时候通过 age->__forwarding->age修改
为什么会使用forwading来查找
///1:为了保持block copy到堆上得时候 指向堆上得__block
源码生成
oc代码
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        __block int a = 10;
       void(^block)(void) = ^{
           a = 20;
           NSLog(@"12334 %d",a);
       };
        block();
    }
    return 0;
}
cpp代码

struct __Block_byref_a_0 {
  void *__isa;
__Block_byref_a_0 *__forwarding;
 int __flags;
 int __size;
 int a;
};
///在生成得时候block得时候,会将__Block_byref_a_0得地址保存到block内部
struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  __Block_byref_a_0 *a; // by ref 
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_a_0 *_a, int flags=0) : a(_a->__forwarding) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};
///初始化过程
int main(int argc, const char * argv[]) {
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 

       __Block_byref_a_0 a = {0,&a, 0, sizeof(__Block_byref_a_0), 10};
       void(*block)(void) = &__main_block_impl_0(__main_block_func_0, &__main_block_desc_0_DATA, &a, 570425344);
       (block->FuncPtr)(block);
    }
    return 0;
}