Search code examples
objective-cobjective-c-blocks

Nested block programming


According to this block programming tutorial:

http://thirdcog.eu/pwcblocks/

The following nested block:

void (^(^myblockptr)(void (^)()))();

Is a pointer to a block returning a block taking a block

It says that it is equivalent to:

typedef void (^Block)();
Block (^myblockptr)(Block);

I guess that (void (^)()) corresponds to the parameters, i.e, (Block). However, I am unable to see which part of the nested expression corresponds to the returned block.

Are you able to identify the returned block in the nested expression?


Solution

  • As Joshua’s said, when analysing C declarations it’s a good idea to start from the inside out.

    void (^(^myblockptr)(void (^)()))();
    

    Since myblockptr is the variable, let’s split the declaration in two parts, to the left of the variable and to the right of the variable:

    void (^(^myblockptr)    (void (^)()))();
    

    We know that (^myblockptr) is a block because of ^, so to its left we should find its return type, and to its right we should find its parameter types.

    Let’s analyse the parameters that myblockptr takes, moving to the right. They should be grouped by parentheses right after the (^myblockptr):

    void (^(^myblockptr)    (void (^)())    )();
    

    It’s a single parameter, which is a block because of ^:

    void (^)()
    

    and now it’s easy to see that the parameter is a block that returns void and takes no parameters.

    Moving farther to the right, there’s a closing parenthesis so we need to analyse the leftmost part:

    void (^    (^myblockptr)…
    

    where we see that myblockptr returns a block that returns void. Since it returns a block, we should find the parameter types accepted by the returned block after the closing parenthesis that matches the leftmost opening paranthesis:

    void (^    (^myblockptr)(void (^)())    )();
    

    since it’s (), we see that the returned block doesn’t have any parameters.

    enter image description here

    In summary: myblockptr is a block that (to the right) accepts a parameter that is a block that takes no parameters and returns void and (to the left) returns a block that takes no parameters and returns void. Since the return type of myblockptr and the (single) parameter type are the same:

    typedef void (^Block)();
    

    leading to:

    Block (^myblockptr)(Block);
    

    You may want to read Steve’s Reading C type declarations and, as mentioned by Jeremy, Fish’s cdecl.org.