block --- 来自于我的理解和使用

block的使用与创建

block object-c 中的匿名函数

最常见的疑问 截取变量

image.png

途中 我们可以看到 age 的值打印的是10 而不是下面修改的18, 就是让很多人有了部分的疑问。
在我看到这段代码的时候,查阅了部分的做资料,了解到了部分底层编译所执行的内容


image.png

Block语法转换成C函数后,Block语法表达式中用到的自动变量会被作为成员变量追加到了__main_block_impl_0结构体中。
而此结构体中的成员变量类型与自动变量类型完全相同,但仅限于Block语法中使用到的自动变量。
因此,所谓“截获自动变量值”意味着执行Block语法时,Block语法表达式所使用的自动变量值被保存到Block的结构体实例中。
这个时候的age, 在底层就是copy了一份,生成了新的对象,和之前的age 是互不影响的。

__block说明符

在Block中修改截获的自动变量值有两种方法。
1.使用静态变量,静态全局变量,全局变量
从Block语法转换成的C语言函数中访问静态全局变量 / 全局变量并没有任何改变,可直接使用。
但是静态变量却是用静态变量的指针来对其进行访问,这是超出作用域使用变量的最简单方法。
2.使用 __block 修饰符

image.png

在这里,age 值是被修改的,那么,为什么使用__block就能修改里面的值呢,我们继续往下走:
通过clang 内部:
···
attribute((blocks(byref))) __Block_byref_val_0 val = {(void*)0,(__Block_byref_val_0 *)&val, 0, sizeof(__Block_byref_val_0), 10};
···
__block 增加了 __Block_byref_val_0结构体类型的自动变量,即栈上生成的__Block_byref_val_0结构体实例
image.png

刚刚在Block中向静态变量赋值时,使用了指向该静态变量的指针。
而向__block变量赋值时,Block的__main_block_impl_0结构体实例会持有指向__block变量的_Block_byref_val_0 结构体实例的指针。
也就是Block的__main_block_impl_0结构体实例会持有一个指针,指向__block修饰的变量所转换的__Block_byref_val_0结构体实例。
而__Block_byref_val_0结构体通过成员变量__forwarding指针访问成员变量val

另外,为了能在多个Block中使用__block变量,__block变量的__Block_byref_val_0结构体并不在Block用__main_block_impl_0结构体中。
Block是通过__Block_byref_val_0结构体实例的指针来访问。

你可能感兴趣的:(block --- 来自于我的理解和使用)