objective-csyntaxobjective-c-blocks

Block Declaration Syntax List


Block syntax in Objective C (and indeed C, I presume) is notoriously incongruous. Passing blocks as arguments looks different than declaring blocks as ivars, which looks different than typedefing blocks.

Is there a comprehensive list of block-declaration syntax that I could keep on hand for quick reference?


Solution

  • List of Block Declaration Syntaxes

    Throughout, let

    And remember that you can create as many parameters as you'd like.

    Blocks as Variables

    Possibly the most common for of declaration.

    return_type (^blockName)(var_type) = ^return_type (var_type varName)
    {
        // ...
    };
    

    Blocks as Properties

    Much like declaring blocks as variables, however subtly different.

    @property (copy) return_type (^blockName) (var_type);
    

    Blocks as Parameters

    Note that this is distinct from "Blocks as Arguments"; in this instance, you're declaring a method that wants a block argument.

    - (void)yourMethod:(return_type (^)(var_type))blockName;
    

    Blocks as Arguments

    Note that this is distinct from "Blocks as Parameters"; in this instance, you're calling a method that wants a block argument with an anonymous block. If you have already declared a block variable, it is sufficient to pass the variable name as the argument.

    [someObject doSomethingWithBlock: ^return_type (var_type varName)
    {
        //...
    }];
    

    Anonymous Block

    This is functionally an anonymous block, however the syntax for assigning blocks to variables is simply to set the variable equal to an anonymous block.

    ^return_type (var_type varName)
    {
        //...
    };
    

    typedef Block

    This allows you to set up a short name that can be referenced just like any other class name during the declaration of blocks.

    typedef return_type (^blockName)(var_type);
    

    To then later use blockName instead of the standard block declaration syntax, simply substitute.

    Inline Block

    This is arguably a less useful utilization of blocks, but may have its place nonetheless. An inline block is an anonymous block called immediately after instantiation.

    ^return_type (var_type varName)
    {
        //...
    }(var);
    

    Inline blocks are primarily useful for scope offsetting, and are roughly equivalent to simple brace-delimited chunks of code.

    {
       //...
    }
    

    Recursive Blocks

    This allows you to call a block from itself, creating a loop that can be used during callbacks and GCD calls. This instantiation method is free of retain cycles in ARC.

    __block return_type (^blockName)(var_type) = [^return_type (var_type varName)
    {
        if (returnCondition)
        {
            blockName = nil;
            return;
        }
    
        // ...
    } copy];
    blockName(varValue);
    

    Returning Blocks

    A method can return a block,

    - (return_type(^)(var_type))methodName
    {
        // ...
    }
    

    as can a function, if a bit strangely.

    return_type (^FunctionName())(var_type)
    {
        // ...
    }
    

    Addendums

    If I've missed anything, please let me know in comments, and I'll research/add them.

    Oh, and in Swift...

    blockName = (varName: var_type) -> (return_type)
    

    It's almost like it's a language feature.