Block Declaration Syntax List

Objective CSyntaxObjective C-Blocks

Objective C Problem Overview


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?

Objective C Solutions


Solution 1 - Objective C

##List of Block Declaration Syntaxes## Throughout, let

  • return_type be the type of object/primitive/etc. you'd like to return (commonly void)
  • blockName be the variable name of the block you're creating
  • var_type be the type object/primitive/etc. you'd like to pass as an argument (leave blank for no parameters)
  • varName be the variable name of the given parameter

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.

Solution 2 - Objective C

I personally like using this website (http://fuckingblocksyntax.com). The name is easier to remember than the block syntax itself:

http://fuckingblocksyntax.com</h2>

and if you can't load URLs with bad words in them you can use this mirror: http://goshdarnblocksyntax.com

fuckingblocksyntax website

Solution 3 - Objective C

Typedef:

typedef void (^block)(NSString *arg);

Inline:

void (^block)(NSString *) = ^(NSString *param) {
  // do something....
};

Method:

- (void)method:(void (^)(NSString *param))handler

Solution 4 - Objective C

The Xcode 4 snippet library contains templates for block typedefs and inline blocks as variables. They are also available via auto-completion (typedefblock and inlineblock).

For blocks as arguments to methods, I'd recommend declaring a typedef and then simply using that. It makes the code much easier to read.

Solution 5 - Objective C

I wrote a completionBlock for a class which will return the values of a dice after they have been shaked:

  1. Define typedef with returnType (.h above @interface declaration)

     typedef void (^CompleteDiceRolling)(NSInteger diceValue);
    
  2. Define a @property for the block (.h)

     @property (copy, nonatomic) CompleteDiceRolling completeDiceRolling;
    
  3. Define a method with finishBlock (.h)

     - (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock;
    
  4. Insert previous defined method in .m file and commit finishBlock to @property defined before

     - (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock{
         self.completeDiceRolling = finishBlock;
     }
    
  5. To trigger completionBlock pass predefined variableType to it (Don't forget to check whether the completionBlock exists)

     if( self.completeDiceRolling ){
         self.completeDiceRolling(self.dieValue);
     }
    

Solution 6 - Objective C

typedef void (^OkBtnBlock)(id data);
typedef void (^CancelBtnBlock)();

@property (nonatomic, strong) OkBtnBlock okBtnBlock;
@property (nonatomic, strong) CancelBtnBlock cancelBtnBlock;

+ (void)foo:(OkBtnBlock)okBtn andCancel:(CancelBtnBlock)btnCancel;

Solution 7 - Objective C

If you need to work back in Xcode 4.2, you can also @synthesize a block declared as a property just like you would with a non block property. Don't let the block syntax throw you.

If your block property is this:

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

Then your @synthesize is this:

@property blockName;

Cheers.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPatrick PeriniView Question on Stackoverflow
Solution 1 - Objective CPatrick PeriniView Answer on Stackoverflow
Solution 2 - Objective CpsyView Answer on Stackoverflow
Solution 3 - Objective CEraView Answer on Stackoverflow
Solution 4 - Objective ComzView Answer on Stackoverflow
Solution 5 - Objective CAlex CioView Answer on Stackoverflow
Solution 6 - Objective CbenhiView Answer on Stackoverflow
Solution 7 - Objective CAlex ZavatoneView Answer on Stackoverflow