Block

什么是block

block:是封装了函数调用以及函数环境的对象

   void(^Block)(void) = ^() {
            int a = 10;
        };
        
        Block();
          NSLog(@"%@",[Block class]);
        NSLog(@"%@",[[Block class] superclass]);
        NSLog(@"%@",[[[Block class] superclass]  superclass]);
        NSLog(@"%@",[[[[Block class] superclass] superclass] superclass]);
/// 打印结果 __NSGlobalBlock__ __NSGlobalBlock NSBlock  NSObject 
证明了block 是对象
###block的三种类型
__NSGlobalBlock__  __NSMallocBlock__  __NSStackBlock__
他们之间的关系
![WechatIMG74.png](https://upload-images.jianshu.io/upload_images/9717104-94f6a32f0cbc2bba.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)




struct __main_block_impl_0 {
struct __block_impl impl;
// void *isa;
//  int Flags;
//  int Reserved;
//  void *FuncPtr;


  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的定义和调用

// 定义
void(*Block)(void) = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));

// 调用
((void (*)(__block_impl *))((__block_impl *)Block)->FuncPtr)((__block_impl *)Block);

// 去掉中间的类型强制转换
 Block->FuncPtr(Block);

变量捕获

Block_第1张图片
D9CC00209815E67B93A3AE79C9DF516D.png

在MRC环境下什么情况block 会执行copy操作
1.返回值是block
2.有强指针指向

循环引用的问题
你中有我我中有你

解决方法:
打破循环引用链

__weak typyof(self) weakself = self;
__unsafe__unretained id weakself = self;
__block id weakself = self;

你可能感兴趣的:(Block)