什么是block?
block是将函数及其执行上下文封装起来的对象。
- 截获变量
截获变量不同类型不同结果
基本数据类型的局部变量截获其值
对象类型的局部变量连同所有权修饰符一起截获
截获即赋值(被截获的局部变量就会在block结构里面形式一个一样的变量)
指针形式 截获局部静态变量
不截获 全局变量 静态全局变量
(获取的是变量的最新的值)
- __block 修饰符
对被截获变量进行赋值操作需要添加__block ————> 赋值不等于使用
赋值 self.array = [nsmutablarray alloc] init];
使用 [ self.array addObject: @"test"]; 的操作 不用添加__block
- 对变量进行赋值时
需要__block
基本数据类型的局部变量
对象类型的局部变量
不需要__block(不截获 全局变量 静态全局变量)
局部静态变量 全局变量 静态全局变量
- block的类型
-
NSConcreteGlobalBlock——> 已初始化数据 ——> copy 什么都没做
-
(当我们声明一个block时,如果这个block没有捕获外部的变量,那么这个block就位于全局区)
-
NSConcreteMallocBlock———> 堆 ——————> copy 增加引用计数
-
(ARC环境下,当我们声明并且定义了一个block,并且没有为Block添加额外的修饰符(默认是strong修饰符)(copy也是在NSConcreteMallocBlock中),如果该Block捕获了外部的变量,实质上是有一个从__NSStackBlock__转变到__NSMallocBlock__的过程,只不过是系统帮我们完成了copy操作,将栈区的block迁移到堆区,延长了Block的生命周期。对于栈区block而言,栈block在当函数退出的时候,该空间就会被回收。)
-
NSConcreteStackBlock——> 栈 ————————>copy 堆
-
(在ARC声明一个block,如果该Block捕获了外部的变量,使用了__weak或者__unsafe__unretained的修饰符,那么系统就不会为我们做copy的操作,不会将其迁移到堆区会在NSConcreteStackBlock;在MRC环境下,我们需要手动调用copy方法才可以将block迁移到堆区)