__block存储类型

__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
", 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'

} 
原文地址:https://www.cnblogs.com/nonato/p/Nonato__block.html