1.可以修改全局变量、静态全局变量、静态局部变量。
那为什么可以修改他们呢?看下面的分析
clang 转换后的代码如下: 可以发现block结构体中没有增加a 和 b 变量, 也就是说转换后,对于全局变量 和 静态全局变量的访问方式和转换前完全一样。
再看 静态局部变量c 是怎么转换的
将c的地址 传给了Block 构造方法
对于静态局部变量,block的处理是:将静态局部变量的地址保存在block中,调用的时候,取出block中这个指针变量,从而得到静态变量的值,进行操作。
2.还可以使用 __block (存储域类说明符)
__block类似于static auto register 等说明符,作用是:将变量值设置到哪个存储域中。
比如 auto 表示作为自动变量存储在栈中
static 表示作为静态变量存储在静态区
__block 变量 转换后到底什么样的呢?
可以看到变成了一个 __Block_byref_a_0 的结构体,这个结构体如下:(图片看不清可以放大)
这个结构体本身中就有一个变量int a 来存储 我们定义的__block int a 的值。
即:__block 将int a 变成了一个叫 __Block_byref_a_0 的结构体,并且结构体中存储这个这个a 的值。这个__block int a = 1; 就变成了一个结构体类型的局部变量,它存在栈区。
再看给__block int a 赋值的代码
转换如下:
首先 Block 结构体 __main_block_impl_0 中持有 __block结构体 __Block_byref_a_0 *a
接着 __block结构体 __Block_byref_a_0 中的__forwaring 持有指向该实例自身的指针,通过成员变量__forwaring访问成员变量 a ( a 是__Block_byref_a_0 实例自身持有的变量,保存了int a 的值)
有2个疑问:__forwaring存在的理由是什么?
block超出变量作用域可存在的理由?
下一篇我会说明。