__block存储类型
你可以指定引入一个变量为可更改的,即读-写的,通过应用__block 存储类型修饰符。局部变量的__block 的存储和 register、auto、static 等存储类型相似,但它们之间不兼容。
__block 变量保存在变量共享的作用域范围内,所有的 blocks 和 block 副本都声明或创建在和变量的作用域相同范围内。所以,如果任何 blocks 副本声明在栈内并未超出栈的结束时,该存储会让栈帧免于被破坏(比如封装为以后执行)。同一作用域范围内给定的多个 block 可以同时使用一个共享变量。
作为一种优化,block存储在栈上面,就像blocks本身一样。如果使用Block_copy 拷贝了 block 的一个副本(或者在 Objective-C 里面给 block 发送了一条 copy 消息), 变量会被拷贝到堆上面。所以一个__block 变量的地址可以随时间推移而被更改。
使用__block 的变量有两个限制:它们不能是可变长的数组,并且它们不能是包含有 C99 可变长度的数组变量的数据结构。
以下举例说明了如何使用__block 变量:
__block int x = 123; // x lives in block storage void (^printXAndY)(int) = ^(int y) { x = x + y; printf("%d %d\n", x, y); }; printXAndY(456); // prints: 579 456 // x is now 579
下面的例子显示了 blocks 和其他几个类型变量间的交互:
extern NSInteger CounterGlobal; static NSInteger CounterStatic; { NSInteger localCounter = 42; __block char localCharacter; void (^aBlock)(void) = ^(void) { ++CounterGlobal; ++CounterStatic; CounterGlobal = localCounter; // localCounter fixed at block creation localCharacter = 'a'; // sets localCharacter in enclosing scope }; ++localCounter; // unseen by the block localCharacter = 'b'; aBlock(); // execute the block // localCharacter now 'a' }