Block

Block内容如下:

  • 关于Block
  • 截获变量
  • __block修饰符
  • Block的内存管理
  • Block的循环引用

1.关于Block

作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS交流群:642363427,不管你是大牛还是小白都欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习成长!

什么是Block
Block是将函数及其执行上下文封装起来的对象 
什么是Block调用
Block调用即是函数的调用 

2.截获变量

int multiplier = 6; int(^Block)(int) = ^int(int num) { return num * multiplier; }; multiplier = 4; NSLog(@"result is %d", Block(2)); 
Block(2) = 12 
截获变量
- 局部变量:基本数据类型;对象类型
- 静态局部变量
- 全局变量
- 静态全局变量 
- 对于基本数据类型的局部变量截获其值
- 对于对象类型的局部变量连同所有权修饰符一起截获
- 以指针形式截获局部静态变量
- 不截获全局变量,静态全局变量 

3. __block修饰符

一般情况下,对被截获变量进行赋值操作需添加__block修饰符 
{ NSMutableArray *array = nil; void(^Block)(void) = ^{ array = [NSMutableArray array]; } Block(); } 是否存在问题? 需要在array声明处添加__block修饰符 
需要__block修饰符 局部变量:1.基本数据类型2.对象类型 
不需要__block修饰符
静态局部变量
全局变量
静态全局变量 
__block int multiplier = 6; int(^Block)(int) = ^int(int num) { return num * multiplier; }; multiplier = 4; NSLog(@"result is %d", Block(2)); 结果为8 __block修饰的变量变成了对象 

4.Block的内存管理

//全局block _NSConcreteGlobalBlock //栈block _NSConcreteStackBlock //堆block _NSConcreteMallocBlock 
  • Block的copy操作


  • 栈上Block的销毁


  • 栈上Block的copy



如上图,思考-栈上的block copy之后,MRC环境下是否会引起内存泄漏?
是的,copy操作之后,堆上的block没有额外的成员变量指向它,正如我们和
alloc对象后,没有进行relese,造成内存泄漏 

5.Block的循环引用

{ _ _ block MCBlock *blockSelf = self; _block = ^int(int num){ return num * blockSelf.var; }; _block(2); } 思考,代码有问题吗? 在MRC下,不会产生循环引用
在ARC下,会产生循环引用 { _ _ block MCBlock *blockSelf = self; _block = ^int(int num){ int result == num * blockSelf.var; blockSelf = nil; return result; }; _block(2); } 

6.面试题

  • 什么是Block?
  • 为什么Block会产生循环引用?
  • 怎样理解Block截获变量的特性?