I'm a beginner to Objective C and iOS development, but a 13-year .NET veteran. I'm having a hard time mentally diagramming the following declaration, which came from the Programming with Objective C guide:
void (^(^a)(void (^) (void))) (void) = ...
It's used as an example of why one should use typedef
to define blocks, but I want to understand what I'm looking at to better get a feel for block definition syntax in the first place.
Here's how I've diagrammed it so far:
Where I'm running into problems is that here is how I understand the basic syntax:
[return_val] (^[block_name]) ([block_args]) = ...
If that's the case, then what I have is a block that returns void and has no arguments, but is named (^a) (void (^) void)
. Meaning the name of my block, rather than being a straight string, is itself a block.
Clearly I'm missing something here. Can someone please shed some light on it? According to the site, it simplifies to this:
typedef void (^SimpleBlock) (void);
SimpleBlock (^complexBlock) (SimpleBlock) = ...
I'm just missing how.
Edit: The third void should have been in parentheses. I fixed that. It's wrong in the image, but I didn't feel like redoing the entire image just for that. :) If it turns out to be the source of my problem, I will fix it here.
In your example you're missing some parentheses for the third void
void (^(^a)(void (^)(void)))(void)
Now let's break it down. The basic syntax to return a block from a function is:
void (^f())(void) {
return ^{};
}
In this example, the returned block takes no arguments and returns void.
Now let's build your example.
void (^myBlock)(void); // Block returning void, taking no args
void (^myBlock)(void (^)(void)); // Block returning void, taking block as arg
int (^myBlock)(void (^)(void)); // Block returning int, taking block as arg
void (^ (^myBlock)(void (^)(void)) )(void); // Block returning block, taking block as arg
I've aligned the central part in each line to make it easier to read. So the difficult part seems to be returning a block. In the last line we used the syntax I described earlier to return a block from a function.
Obviously the typedefs
make it much easier to read.
EDIT:
Consider this example where, in the first line, i replace int
for a block
with the intuitive return syntax:
void (^ )(void) (^myBlock)(void (^)(void)); // Syntax we 'intuitively would use'
void (^ (^myBlock)(void (^)(void)) )(void); // Official syntax
I'm not 100% sure of what I'm about to say, but my suspicion is that the reason for this weird syntax is so that the parser in the compiler doesn't get confused. The first 'intuitive' syntax would make the compiler think that we have a block taking no arguments returning void, and the remaining characters would be considered syntax error.
In my opinion, syntax is something you don't question too much (you can criticize it, of course) because it's part of the design on a language, and we have to follow the rules (set by some hopefully smart engineers) for our code to compile.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With