这是我参与「第四届青训营 」笔记创作活动的的第7天
今天是7月29日,今天进行有关OC中Block(闭包)的学习。对相关笔记进行整理归纳总结。
闭包的基本定义
闭包在实现上是一个结构体,存储了一个函数(通常是一个入口地址)和一个关联的环境(相当于一个符号查找表)。环境中既要包括环境变量也要包括自由变量。闭包在OC中的实现为block。
block可以接受参数也可以有返回值,block可以分配在栈和堆上,也可以是全局的。分配到栈上的块可以拷贝到堆中。
声明格式:returnType (^blockName)(int a)=^(int a){};,返回值类型 (^闭包名)(传入的参数)
简略声明:returnType (^blockName)(int)=^(int a){}; ,返回值类型 (^闭包名)(传入的参数类型),省略了传入参数的变量名。
typedef声明:typedef returnType (^blockName)(parameters);,typedef 返回值类型 (^闭包名)(传入的参数);
block内存管理
NSGlobalblock:全局Block,保存在数据区(.data段),定义在全局区或者没有访问自动局部变量的环境
NSStackBlock:栈Block,保存在栈区,当访问自动局部变量时使用
NSMallocBlock:堆block,保存在堆区,出现在NSStackBlock调用copy的环境
NSStackBlock自动调用copy的几种情形:当block作为函数返回值时;当将block赋值给strong指针时;当
int age = 8;
void(^stackBlock)(void) = ^{
NSLog(@"Hello, World! %d", age);
};
NSLog(@"%@", [stackBlock class]);//输出结果为NSMallocBlock
输出为
变量捕获
代码运行后结果为value1=1,value2=2,那是为什么呢?
因为运行第9行代码之前,oneblock已经在4-6行将value的值捕获了,在第8行代码运行后不能影响oneblock内捕获的value值。之后在第9行运行oneblock。这为变量捕获中的值捕获
代码运行后结果为value1=2,value2=3,那是为什么呢?
因为__bolck关键字允许被修饰变量(value)在block中被修改,所以在第9行代码运行后oneblock中的value也随之变化,运行oneblock后value为3,11行输出value为3.这为变量捕获中的名称引用
代码运行后结果为value1=2,value2=2,那是为什么呢?
因为block在这段代码中实际捕获的是self,而不是name,即使name变化,也不影响捕获self来获取name,所以两个输出都为2.
总结
今天了解到了OC中的闭包,了解到了block的概念和使用,以及block是如何捕获变量的。变量捕获中的捕获规则是这章内容比较容易想通的地方,需要多理解代码。