__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' }