Block中可以修改全局变量,全局静态变量,局部静态变量吗?

107次阅读

共计 908 个字符,预计需要花费 3 分钟才能阅读完成。

原文:iOS 面试题大全

可以. 深入研究 Block 捕获外部变量和__block 实现原理

全局变量和静态全局变量的值改变,以及它们被 Block 捕获进去,因为是全局的,作用域很广
静态变量和自动变量,被 Block 从外面捕获进来,成为__main_block_impl_0 这个结构体的成员变量
自动变量是以值传递方式传递到 Block 的构造函数里面去的。Block 只捕获 Block 中会用到的变量。由于只捕获了自动变量的值,并非内存地址,所以 Block 内部不能改变自动变量的值。
Block 捕获的外部变量可以改变值的是静态变量,静态全局变量,全局变量

Block 就分为以下 3 种

_NSConcreteStackBlock: 只用到外部局部变量、成员属性变量,且没有强指针引用的 block 都是 StackBlock。StackBlock 的生命周期由系统控制的,一旦返回之后,就被系统销毁了, 是不持有对象的
_NSConcreteStackBlock 所属的变量域一旦结束,那么该 Block 就会被销毁。在 ARC 环境下,编译器会自动的判断,把 Block 自动的从栈 copy 到堆。比如当 Block 作为函数返回值的时候,肯定会 copy 到堆上

_NSConcreteMallocBlock: 有强指针引用或 copy 修饰的成员属性引用的 block 会被复制一份到堆中成为 MallocBlock,没有强指针引用即销毁,生命周期由程序员控制, 是持有对象的
_NSConcreteGlobalBlock: 没有用到外界变量或只用到全局变量、静态变量的 block 为_NSConcreteGlobalBlock,生命周期从创建到应用程序结束, 也不持有对象

ARC 环境下,一旦 Block 赋值就会触发 copy,__block 就会 copy 到堆上,Block 也是__NSMallocBlock。ARC 环境下也是存在__NSStackBlock 的时候,这种情况下,__block 就在栈上
ARC 下,Block 中引用 id 类型的数据有没有__block 都一样都是 retain,而对于基础变量而言,没有的话无法修改变量值,有的话就是修改其结构体令其内部的 forwarding 指针指向拷贝后的地址达到值的修改

正文完
 0