在Objective-C中定义定义一个接受一个Block并返回一个Block的Block的语法 [英] Syntax to define a Block that takes a Block and returns a Block in Objective-C
问题描述
I find in Apple's document Working with Blocks that the syntax to define a block that returns the result of multiplying two values:
double (^multiplyTwoValues)(double, double);
与定义一个将另一个块作为参数并返回另一个块的块不同:
is different than defining a block that takes another block as an argument and returns yet another block:
void (^(^complexBlock)(void (^)(void)))(void);
为什么第二种语法不是void (^)(void)(^complexBlock)(void (^)(void))
?
Why is the second syntax not void (^)(void)(^complexBlock)(void (^)(void))
?
推荐答案
这就是C语法的工作方式. Block语法基于函数指针的语法,归结为Dennis Ritchie的想法,事物的声明应该看起来像是在使用该事物."
This is just how C syntax works. The Block syntax is based on that of function pointers, which boils down to Dennis Ritchie's idea that "the declaration of a thing should look like the use of that thing".
如果要使用定义的复杂块",然后还要在同一行中调用返回的块,则看起来像这样:
If you were to use the "complex Block" you defined, and then to also call the returned Block in the same line, it would look like this:
complexBlock(void (^argBlock)(void){ /*...*/ })();
// ^ Argument (a literal Block) to the main Block
// ^ Invocation of the returned Block
此外,C声明的解析遵循所谓的左右规则".第一步是查找标识符".您的声明是complexBlock
.
Further, the parsing of C declarations follows a so-called "right-left rule". The first step is "find the identifier". For your declaration, that's complexBlock
.
void (^(^complexBlock)(void (^)(void)))(void);
// | ! | Found identifier: "complexBlock is..."
然后,向右看.我们在圆括号中打了一个括号,所以这就是声明"unit"的结尾.
Then, look to the right. We hit a closing parenthesis, so this is the end of a declaration "unit".
void (^(^ )(void (^)(void)))(void);
// | ! Right parenthesis closes a part of the declaration
返回当前部分的开头,并向左阅读,直到左括号为止.我们找到表示方块类型的插入符号.继续向左看,找到左括号,关闭声明的这一部分.
Go back to the beginning of the current part, and read leftwards until an opening parenthesis. We find the caret indicating a Block type. Keep reading left, and find an opening parenthesis, closing off this part of the declaration.
void (^(^ (void (^)(void)))(void);
// |! | "...a Block..."
接下来,再往右走.在这里,我们找到了一个圆括号,表示参数列表的开始.由于您担心返回类型,因此可以跳过参数列表,但是将其解析为独立的声明.
Next, go right again. Here we find an opening parenthesis, indicating the start of a parameter list. Skip the parameter list since you're concerned with the return type, but it's parsed as a standalone declaration would be.
void (^ (void (^)(void)))(void);
// | ! | "...taking something or other and returning..."
现在我们已经消耗了参数列表:
Now that we've consumed the parameter list:
void (^ )(void);
// | |
继续向右移动,我们在右括号后面打了一个
continue moving right, and we hit a closing parenthesis:
void (^ )(void);
// | !
因此,再次回到当前部分的开头,然后向左移动我们找到方块"插入符的位置.
So, again, back up to the beginning of the current part and move left where we find the Block caret.
void (^ (void);
// ! | "...a Block.."
以下是您对此声明有疑问的关键部分:
向左移动,我们又找到了一个圆括号,因此我们返回右移.这就是为什么返回Block的参数列表位于声明的末尾.
Moving left, again we find an opening parenthesis, so we return to moving right. That's why the return Block's parameter list goes at the end of the declaration.
void ( (void);
// ! | Left parenthesis closes part of declaration,
// **now move rightwards again**
经历了所有这些之后,其余的应该是不言而喻的.
Having gone through all that, the rest should be self-evident.
顺便说一句,我链接到的关于左右规则的页面有一些类似我的演示,其中之一涉及函数指针. http://cdecl.org 也可能使您感到很有趣,它是解析C声明和可以帮助您了解羊毛品种.
Incidentally, the page I linked to about the right-left rule has a few demonstrations like mine, one of which involves function pointers. You may also be amused by http://cdecl.org, which is an online implementation of a program that parses C declarations and can help you understand the woolier varieties.
这篇关于在Objective-C中定义定义一个接受一个Block并返回一个Block的Block的语法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!