Block
Block内容如下:
- 关于Block
- 截获变量
- __block修饰符
- Block的内存管理
- Block的循环引用
1.关于Block
什么是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的内存管理.png//全局block
_NSConcreteGlobalBlock
//栈block
_NSConcreteStackBlock
//堆block
_NSConcreteMallocBlock
-
Block的copy操作
Block的copy操作.png -
栈上Block的销毁
栈上Block的销毁.png -
栈上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截获变量的特性?
QQ交流群: 796142709
网友评论