block对变量的捕获

block、变量、捕获

iOS - block变量捕获原理

1. OC变量

OC变量包括基础变量指针变量

  • 指针的定义:如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。编译系统根据程序中定义的变量类型,分配一定长度的空间。例如,Visual C++ 为整形变量分配4个字节,为单精度浮点类型分配4个字节,为字符型变量分配1个字节,内存区的每一个字节都有一个编号,这就是地址。由于通过地址能找到所需的内存单元,可以说,地址指向该变量单元。 因此,将地址形象化地称为”指针“

  • 基础变量比如 NSInteger a = 10,a 就是基础变量。

  • 指针变量: 如果有一个变量专门用来存放另一个变量的地址(即指针),则它 称为指针变量。即:指针变量的值是另一个变量的内存地址。比如:NSInteger a = 10, NSInteger *pointer = &a,pointer即为指针变量。指针变量前面的 * 表示该变量为指针型变量。指针变量名是pointer。

  • 所以,指针指针变量是2个概念。例如,可以说变量i的指针是2000,而不能说i的指针变量是2000。指针是一个地址,而指针变量是存放地址的变量。

2. block对变量的捕获

  • 局部变量

block里面使用局部变量,是对局部变量的值的捕获。分别对基础变量和指针型变量进行内存地址的打印:在这里插入图片描述
在这里插入图片描述
可以看出, block里面打印的内存地址都发生了变化,所以在block里面的已经是一个新的变量了,只是捕获了block外面变量的值而已

  • 静态变量

block里面使用静态变量,是对该变量的指针的捕获,分别对基础变量和指针变量进行内存地址的打印:
在这里插入图片描述
在这里插入图片描述
可以看出,在block里面打印的内存地址都并未发生变化,所以block里面的仍旧是原来的变量,所以,block对于静态变量是对该变量指针的捕获

  • __block修饰的局部变量

对于__block修饰的局部变量,在block里面使用的时候,也是对该变量指针的捕获,但是因为该变量从栈上被拷贝到了堆上,所以该变量的地址发生了变化。

  • 全局变量和全局静态变量

对于全局变量来说,其存储是在静态数据存储区,在程序结束之前都不会被释放,在 block 中不用捕获,可以直接对其进行修改。