Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Objective-C block still work without copying it to the heap?

I have a simple method in my class:

- (void)getFormWithBlock:(DataCenterResultBlock)block {
    [SomeClass doSomeLongOperationWithParam:someParam 
                                  completionBlock:^(NSData *data, NSURLResponse *response) {
                                      //Success
                                      block(aVar, YES);
                                  } errorBlock:^(NSError *error) {
                                      //Failed
                                      block(nil, NO);
                                  }];
}

I read that you should copy blocks to the heap if you are doing something asynchronously because they are allocated on stack and once the call tree rewinds it will be gone.

But here, I am not copying it to heap but still I get no crash. Why? Thanks

like image 861
0xSina Avatar asked Jul 11 '12 13:07

0xSina


2 Answers

Block variables are copied to the heap automatically by ARC compilers:

7.5. Blocks

...

__block variables of retainable object owner type are moved off the stack by initializing the heap copy with the result of moving from the stack copy.

EDIT I think I misunderstood the question: you asked about block objects themselves, not block variables. The answer in this case is slightly different, but it boils down to the same this: ARC does the correct thing automatically.

ARC knows that block literals must be copied if they're used after the current scope returns. Non-ARC code needs to explicitly copy and autorelease returned blocks:

return [[^{
    DoSomethingMagical();
} copy] autorelease];

With ARC, this simply becomes:

return ^{ DoSomethingMagical(); };

(from here)

like image 130
Sergey Kalinichenko Avatar answered Nov 16 '22 01:11

Sergey Kalinichenko


[SomeClass doSomeLongOperationWithParam:completionBlock:errorBlock:] should be copying the completion and error blocks.

If you look at the implementation of that method, it is probably doing the right thing and copying the block that you passed in. ARC or no ARC, that method should copy those blocks.

like image 35
Firoze Lafeer Avatar answered Nov 16 '22 02:11

Firoze Lafeer