Block原理

  •  Block原理
  •  Block自动截获局部变量

Block原理

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    
    void (^blk)(void) = ^{
        printf("Block
");
    };
    
    blk();
    
    return 0;
}
clang -rewrite-objc main.m  //执行命令生成main.cpp

主要代码摘要如下:

// __block_impl
struct __block_impl {
  void *isa;  
  int Flags;    // 标记
  int Reserved; // 今后版本升级所需要的区域
  void *FuncPtr;// 要调用的函数指针
};
// __main_block_impl_0即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; // _NSConcreteStackBlock相当于class_t结构体实例,联想OC对象中的isa指针的功能保持该对象对应的类的结构体,由此可见Block其实就是OC对象
    impl.Flags = flags;
    impl.FuncPtr = fp; 
    Desc = desc;
  }
};
// __main_block_func_0 
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {

        printf("Block
");
    }
// __main_block_desc_0
static struct __main_block_desc_0 {
  size_t reserved;  // 今后升级所需要的区域 
  size_t Block_size;// block的大小
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};

int main(int argc, const char * argv[]) {
    /* 构造函数调用,去掉转换部分等价于
   struct
__main_block_impl_0 *tmp = __main_block_impl_0(__main_block_func_0,&__main_block_desc_0_DATA);
   struct __main_block_impl_0 *blk = tmp; 栈上生成的结构体实例的指针tmp,赋值给结构体指针类型的变量blk
    */
    void (*blk)(void) = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));
    /*
去掉转换部分等价于
   (*blk->impl.FunPtr)(blk); 使用函数指针调用函数
  */ ((
void (*)(__block_impl *))((__block_impl *)blk)->FuncPtr)((__block_impl *)blk); return 0; }

源码下载

Block自动截获局部变量

1、什么是自动截获局部变量:在执行block语法的时候,block语法表达式所使用的局部变量被保存到block的结构体实例中(没有使用的变量不会被追加)。

2、自动截获局部变量带来的问题:自动截获局部变量仅截获局部变量的值,block中在使用局部变量之后,在block结构体实例中重写该局部变量也不会改变原来截获的自动变量的值。

     

   

原文地址:https://www.cnblogs.com/imChay/p/6019477.html