Search code examples
c++objective-cc++11lambdablock

Apple Blocks vs C++11 Lambdas


I"ve been playing around with C++11 and Apple blocks, and I've tried to create sort of an interator function. The code:

#include <functional>
#include <stdio.h>

void range(int low, int high, int& ref, std::function<void(void)> block){
    int a = low;
    while(a < high){
        ref = a;
        block();
        a++;
    }
}

void range(int low, int high, int& ref, void (^block)(void)){
    int a = low;
    while(a < high){
        ref = a;
        block();
        a++;
    }
}

int main(){
    int a = 0;
    range(0, 5, a, [&](){
        printf("%i\n", a);
    });

    int b = 0;
    range(0, 5, b, ^(){
        printf("%i\n", b);
    });
}

The first one, using C++11 Lambdas worked as I expected, and gives the following output

0
1
2
3
4

The second one, using the Apple Blocks API, gives 5 zeroes, is there any way to make it work for blocks too?


Solution

  • Quoting from the source directly:

    Only the value is captured, unless you specify otherwise. This means that if you change the external value of the variable between the time you define the block and the time it’s invoked, the value captured by the block is unaffected.

    The value captured is a copy of int b which has an initial value of 0.

    Then they go on to specify:

    If you need to be able to change the value of a captured variable from within a block, you can use the __block storage type modifier on the original variable declaration.

    And they provide the following code sample:

    __block int anInteger = 42;
    
    void (^testBlock)(void) = ^{
        NSLog(@"Integer is: %i", anInteger);
    };
    
    anInteger = 84;
    testBlock(); // Prints "Integer is: 84"
    

    I advise you to stick with Lambdas.