Thursday, May 17, 2012

Blocks (2)

Continuing from the previous post, here we see the ability of a block to access (and modify) variables in the enclosing scope. The first type of block takes an int, multiplies it by a second int defined in main but not passed as an argument, and returns the result. It also accesses the variable c (a char *) in main, and changes its value. The change happens before the second block runs as shown by the result of strcmp, which returns 0 for a match, resulting in the assignment of c to a third value.

// clang blocks.m -o prog -framework Foundation -fobjc-gc-only
#import <Foundation/Foundation.h>

typedef int (^A) (int x);
typedef void (^B) ();

int main(int argc, char * argv[]){
    int y = 7;
    __block char *c = "abc\0";
    printf("initial: %s\n", c);
    const char *c2 = "def\0";
    
    A a = ^(int x) { 
        c = (char *) c2;
        return x*y;
    };
    
    B b = ^() { 
        if (!(strcmp(c,c2))) {
            c = "ghi\0"; 
        }
    };
    
    printf("a(2) returns: %i\n", a(2));
    printf("before b(): %s\n", c);
    b();
    printf("after b(): %s\n", c);
    return 0;
}


Output:
> ./prog
initial: abc
a(2) returns: 14
before b(): def
after b(): ghi