Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS block object without copying?

Recently I learn that if I need to keep a block object, I should copy the block, because it's created on the stack.

Then I review some of my code. I found that I was doing something like:

@implementation MyView
...
-(void) addButton:(NSString *)title clickAction:(void ^(void)) action {
    [self.buttons addObject:@[ title, action ] ];
}
-(void) createButtons { ... }
...
@end

...

// Somewhere in my project:
-(void) init {
     MyView *view = [MyView new];
     [view addButton:@"OK"     clickAction:^{ NSLog(@"OK");     }];
     [view addButton:@"Cancel" clickAction:^{ NSLog(@"Cancel"); }];
}

Basically, I add some buttons info to MyView. At some point, MyView will create the buttons. When the button is click, MyView will find out the corresponding clickAction, and invoke it.

The weird part is that this program works fine, no exception, no error.

So, why the program runs without copying the block object?

Other info : * iphone app ( 4.3 - 6.0 ) * non-ARC * XCode 4.5

like image 530
MorrisLiang Avatar asked Mar 07 '26 15:03

MorrisLiang


1 Answers

Behind the scene, block implementation consists of two parts:

  • The executable code of the block, and
  • A data structure containing the values of the variables used in the block

Only the second part of the block is placed on the stack and copied to the heap memory; the first part is compiled to the code segment of your program, and does not get copied.

Since your block implementations do not reference any variable from the surrounding scope, the data portion of their blocks is empty. That is why your code works: there is simply nothing to copy! However, you should add block copy anyway, because otherwise a small change to the code of your block will break your application without the compiler noticing anything.

like image 109
Sergey Kalinichenko Avatar answered Mar 09 '26 03:03

Sergey Kalinichenko