ishahak ishahak - 7 months ago 35
iOS Question

A Tricky Objective-C Blocks Behavior

I'd be glad to get explanation for the following behavior:

typedef void (^MyBlock)(void);
MyBlock g_ary[4];

int runBlockParam2(MyBlock callbackBlock, int num) {
g_ary[num] = callbackBlock;
return num+100;

int main(int argc, const char * argv[]) {
@autoreleasepool {
int i;
for (i=0; i<4; i++) {
__block int j;
int k = runBlockParam2(^{
NSLog(@"in the block i=%i, j=%i", i, j);
}, i);
for (i=0; i<4; i++) {
return 0;

The above code shows the following output:

in the block i=0, j=100
in the block i=1, j=101
in the block i=2, j=102
in the block i=3, j=103

Why is
modified by the assignment which follows the block?

It is interesting to mention that if we remove the
modifier, we will get this:

in the block i=0, j=0
in the block i=1, j=100
in the block i=2, j=101
in the block i=3, j=102

I'll appreciate any explanation to the above behavior!

dan dan

The __block storage type causes any changes to the variable outside of the block to be seen inside of the block and vice-versa. Your j = k line runs before the block itself is run in your second for loop so the block sees j after it has been assigned.

Removing the __block causes the block to capture the value of j as it is when the block is created which is before the assignment. You're invoking undefined behavior after removing the __block because you are capturing j before it has been initialized which leads to the strange output.

If you change your declaration to int j = 0 then the log statements would all show j=0 as you would expect.