multipart-message nevyn bengtsson's blog

featured articles 🦄, about, archive, tags

The One Objective-C Block Memory Management Example You Need To Read

This is what I wish they would have shown us at WWDC, so that I would have understood block memory management and wouldn’t have felt like I had to write an entire frickin’ guide to help others avoid my confusion:
typedef void(^BasicBlock)(void);

void doStuff(BOOL cool) {
    BasicBlock block;
    if(cool)
        block = ^ { ... };
    else
        block = ^ { ... };
}

… roughly translates to …

void doStuff(BOOL cool) {
    BasicBlock block;
    if(cool) {

        struct Block_literal_1 blockStorage1 = ...;
        block = &blockStorage1;

    } // blockStorage1 falls off the stack here

    else 

    {

        struct Block_literal_1 blockStorage2 = ...;
        block = &blockStorage2;

    } // blockStorage2 falls off the stack here


    // and block thus points to non-existing/invalid memory here.
    ...
}

… which is why you need to do this, to move the block to the heap:

void doStuff(BOOL cool) {
    BasicBlock block;
    if(cool)
        block = Block_copy(^ { ... });
    else
        block = Block_copy(^ { ... });
    ...
}

(which in Cocoa is block = [[^ { ... } copy] autorelease]

This example applies to returning blocks from functions or methods, storing blocks in collections, storing them in instance variables and other variables on the heap, and so on.

(Sudden realization and example inspiration brought to you by the Clang Block Implementation Specification)

Tagged flattr