Friday, May 18, 2012

Blocks (4)

In the spirit of quick Objective-C, here is another example using blocks. We feed a bunch of blocks to NSOperationQueue. According to the docs

The block should take no parameters and have no return value.

So then the question is what can the block do? In this example, we get values from a loop counter and also call a function defined in the same file.

A run loop is required in order to see any output (and the output is truncated if the run loop's time interval is shortened).

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

void f() { printf("."); }
typedef void (^B)();

int main(int argc, char * argv[]) {
    NSOperationQueue *q = [NSOperationQueue mainQueue];
    int N = 100;
    __block int c = 0;
    NSLog(@"%p", &f);
    NSLog(@"%p", &main);
    NSLog(@"%p", &c);
    B b = ^() { 
        f();
        c++;
        if (c && !(c%(N/10))) {
            printf("c = %3d\n", c); 
            }
        };
    NSLog(@"%p", &b);
    B b2 = [b copy];
    NSLog(@"%p", &b2);

    for (int i = 0; i < N; i++) {
        [q addOperation:[NSBlockOperation blockOperationWithBlock:b]];
    }
    NSRunLoop* rl = [NSRunLoop currentRunLoop];
    NSLog(@"%p", &rl);
    [rl runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.2]];
    return 0;
}
Output:
> ./prog
2012-05-19 08:53:26.881 prog[2988:707] 0x103da99c0
2012-05-19 08:53:26.883 prog[2988:707] 0x103da99e0
2012-05-19 08:53:26.883 prog[2988:707] 0x7fff639a7ba8
2012-05-19 08:53:26.884 prog[2988:707] 0x7fff639a7b88
2012-05-19 08:53:26.884 prog[2988:707] 0x7fff639a7b88
2012-05-19 08:53:26.885 prog[2988:707] 0x7fff639a7b50
2012-05-19 08:53:26.887 prog[2988:707] 0x7fff639a7b40
..........c =  10
..........c =  20
..........c =  30
..........c =  40
..........c =  50
..........c =  60
..........c =  70
..........c =  80
..........c =  90
..........c = 100
From what I understand, I expected the first block to be in a different place than the copy, but they both appear to be on the heap. The first two variables, main and f, are on the stack.

This isn't a particularly useful example. I have to look into things some more to find a good toy example for concurrent execution.