Saturday, April 2, 2016

IOS - Maintaining a Block in Memory

IOS - Maintaining a Block in Memory

In Objective-C extension/block specification - "All Blocks are constructed to be Objective-C objects regardless of whether the Objective-C runtime is operational in the program or not. ", and they have the same memory layout. This consists primarily of its captured variables. Specifically for blocks the actual code is not stored in the memory but in a different part of the memory(text) with the rest of the executable code on your app.
When a block is created, the data associated with it are stored in the stack, including variables in its scope that it has taken a snapshot of. (The stack is a temporary memory that, in the form of a stack frame for the currently executing C function, stores information needed for executing that function--function parameters, local variables, and control information.)
When objective-c block goes out of scope, this memory ‘in place’ is subject to reallocation and then the block will be no longer valid.
If a block is used in the parameter of a method that is synchronous--that is, the code calling the block waits for the method to perform its computations before going on--there is no problem. The block will continue to be in scope, and its stack frame will still be there and available to the method being called.
If the method is asynchronous, however, the call of the method only starts its computation, which continues after the return of the method--there is a potential problem. The memory for the block may be overwritten before the code in the block executes. To avoid this problem it is common practice for an asynchronous method to copy the block from the stack to the heap by performing a copy operation. (The heap is the much larger and more permanent memory that contains segments of memory that the program can request.)
If it is otherwise desired to execute the block outside the scope it was created in, the block also needs to be copied to heap memory.

So, now let's see a block copy:

A block can be copied by sending a copy message to the block.

    void (^simplestThiagoBlock) (void);
    simplestBlock = ^{
         NSLog(@"Hi, I'm a Thiago’s block.");
 
    };
    [simplestThiagoBlock copy];

Please, understand that copying the block to the heap makes it subject to reference counting. If manual reference counting is used, the block should be released when no longer needed. So, keep this in mind in future.
In general, it is rare that you will need to copy a block. The first copy will move the block from the stack to the heap. Successive copies do nothing then only increasing the retain count. If you need to make an actual copy of a block, better you will need to recreate it.

Happy coding,
Thiago Leoncio.