-1

I am new to Objective-C, I was following Apple's "Programming with Objective_C", I can't understand this code sample:

void (^(^complexBlock)(void (^)(void)))(void) = ^ (void (^aBlock)(void)) {
 //some code
 return ^{
 //some code
 };
};

I was expecting this pattern:

ReturnType ^(blockVariableIdentifier)(ParameterType1, ParameterType2, ...) = ^{  
   //some code
   };
  1. How was blockVariableIdentifier repleaced with (^complexBlock)(void (^)(void)) ?
  2. isn't it supposed to have void as a return, how come that we have return { ... } ?

I find this code confusing, can you explain it ?

code source.

Update:

Given this typedef:

typedef void (^XYZSimpleBlock)(void);

I can simplify the declaration of complexBlock to:

void (^(^complexBlock)(XYZSimpleBlock))(void);

but I still can't figure out how this is equivalent to

XYZSimpleBlock (^betterBlock)(XYZSimpleBlock);

Amr Lotfy
  • 2,937
  • 5
  • 36
  • 56
  • 1
    It's confusing, what don't you understand? Or, maybe it's easier, could you write down what you think/understand/don't understand ? That way we can simply correct where you're wrong and not downvote, because it looks like you didn't put much effort in this :P – Gil Sand May 05 '15 at 13:59
  • 1
    @AmrLotfy I updated my answer with `typedef` of `XYZSimpleBlock` and some explanation on return types – Azat May 05 '15 at 14:51
  • 1
    You can find the answer in [this post](http://stackoverflow.com/questions/22057215/understanding-complex-block-syntax). – Ahmed Lotfy May 05 '15 at 18:20

2 Answers2

4

It is said right there at your link:

The complexBlock variable refers to a block that takes another block as an argument (aBlock) and returns yet another block.

This is just block that returns another block. There is also simplification of that code:

typedef void (^XYZSimpleBlock)(void);
XYZSimpleBlock (^betterBlock)(XYZSimpleBlock) = ^(XYZSimpleBlock aBlock) {
    ...
    return ^{
        ...
    };
};

Return type of betterBlock is XYZSimpleBlock so you return another block from there. void relates only for XYZSimpleBlock, look at its typedef - block that have no arguments and do not return anything

Also this awesome answer will be useful to you

Community
  • 1
  • 1
Azat
  • 6,745
  • 5
  • 31
  • 48
1

According to this answer (found in @Ahmed Lotfy's comment above) this is just a matter of language/compiler design, but to visuailze how that happened I made this image:

  1. The expected syntax (top) of a block that takes a block as argument and returns a block, that is not accepted by Xcode.

  2. The desgined syntax (bottom).

enter image description here

Visually what happened is just cutting the boxed )(void) and putting it at the end.

we can see it as analogy to a functin returning a block:

void (^f())(void) { 
 return ^{ ... }; 
}

just by substituting f() with (^myBlock)(void (^) (void)) which is a block taking another block as a parameter with no return.

I hope we can live with that.

Community
  • 1
  • 1
Amr Lotfy
  • 2,937
  • 5
  • 36
  • 56