lu *_*uan 10 syntax declaration objective-c objective-c-blocks
我在Apple的文档"使用块"中找到了定义块的语法,该块返回乘以两个值的结果:
double (^multiplyTwoValues)(double, double);
Run Code Online (Sandbox Code Playgroud)
不同于定义一个块,该块将另一个块作为参数并返回另一个块:
void (^(^complexBlock)(void (^)(void)))(void);
Run Code Online (Sandbox Code Playgroud)
为什么第二种语法不是void (^)(void)(^complexBlock)(void (^)(void))?
Jos*_*ell 19
这就是C语法的工作原理.Block语法基于函数指针的语法,这可以归结为Dennis Ritchie的观点,即"事物的声明应该看起来像使用那个东西".
如果你使用你定义的"复杂块",然后也在同一行中调用返回的块,它将如下所示:
complexBlock(void (^argBlock)(void){ /*...*/ })();
// ^ Argument (a literal Block) to the main Block
// ^ Invocation of the returned Block
Run Code Online (Sandbox Code Playgroud)
此外,C声明的解析遵循所谓的"右 - 左规则".第一步是"找到标识符".对于你的声明,那是complexBlock.
void (^(^complexBlock)(void (^)(void)))(void);
// | ! | Found identifier: "complexBlock is..."
Run Code Online (Sandbox Code Playgroud)
然后,向右看.我们点了一个右括号,所以这是声明"单位"的结尾.
void (^(^ )(void (^)(void)))(void);
// | ! Right parenthesis closes a part of the declaration
Run Code Online (Sandbox Code Playgroud)
返回当前部分的开头,向左阅读直到左括号.我们发现插入符号表示块类型.继续阅读,找到一个左括号,关闭声明的这一部分.
void (^(^ (void (^)(void)))(void);
// |! | "...a Block..."
Run Code Online (Sandbox Code Playgroud)
接下来,再次右转.这里我们找到一个左括号,表示参数列表的开始.跳过参数列表,因为您关注的是返回类型,但它被解析为独立声明.
void (^ (void (^)(void)))(void);
// | ! | "...taking something or other and returning..."
Run Code Online (Sandbox Code Playgroud)
现在我们已经使用了参数列表:
void (^ )(void);
// | |
Run Code Online (Sandbox Code Playgroud)
继续向右移动,我们点了一个右括号:
void (^ )(void);
// | !
Run Code Online (Sandbox Code Playgroud)
所以,再次,回到当前部分的开头,然后向左移动,我们找到Block插入符号.
void (^ (void);
// ! | "...a Block.."
Run Code Online (Sandbox Code Playgroud)
这是关于此声明的问题的关键部分:
向左移动,我们再次找到一个左括号,所以我们返回向右移动.这就是返回Block的参数列表在声明结束时的原因.
void ( (void);
// ! | Left parenthesis closes part of declaration,
// **now move rightwards again**
Run Code Online (Sandbox Code Playgroud)
经历了这一切,其余的应该是不言而喻的.
顺便提一下,我链接到关于左右规则的页面有一些像我一样的演示,其中一个涉及函数指针.您也可以通过逗乐http://cdecl.org,这是一个在线的实现,解析C声明,可以帮助你了解woolier品种计划.