理解复杂的块语法

Ari*_*oth 11 objective-c ios objective-c-blocks

我是Objective C和iOS开发的初学者,但是13年的.NET资深人士.我很难在心理上绘制以下声明,这些声明来自Objective with Objective C指南:

void (^(^a)(void (^) (void))) (void) = ...
Run Code Online (Sandbox Code Playgroud)

它用作为什么应该typedef用来定义块的一个例子,但是我想要了解我正在寻找的内容,以便首先更好地理解块定义语法.

这是我到目前为止的图表:

在此输入图像描述

我遇到问题的地方是我理解基本语法的方式:

[return_val] (^[block_name]) ([block_args]) = ...
Run Code Online (Sandbox Code Playgroud)

如果是这种情况,那么我所拥有的是一个返回void且没有参数但被命名的块(^a) (void (^) void).这意味着我的块的名称,而不是一个直的字符串,本身就是一个块.

显然我在这里遗漏了一些东西.有人可以对此有所了解吗?根据该网站,它简化为:

typedef void (^SimpleBlock) (void);
SimpleBlock (^complexBlock) (SimpleBlock) = ...
Run Code Online (Sandbox Code Playgroud)

我只是想念如何.

编辑:第三个空格应该在括号中.我修好了.它在图像中是错误的,但我不想为此重做整个图像.:)如果它原来是我的问题的来源,我会在这里修复它.

Mer*_*ede 10

在你的例子中,你错过了第三个括号 void

void (^(^a)(void (^)(void)))(void)
Run Code Online (Sandbox Code Playgroud)

现在让我们分解吧.从函数返回块的基本语法是:

void (^f())(void) { 
    return ^{}; 
}
Run Code Online (Sandbox Code Playgroud)

在此示例中,返回的块不带参数并返回void.

现在让我们构建您的示例.

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
Run Code Online (Sandbox Code Playgroud)

我已经对齐了每一行的中心部分,以便于阅读.所以困难的部分似乎正在回归一个街区.在最后一行中,我们使用前面描述的语法从函数返回一个块.

显然,typedefs让它更容易阅读.

编辑:
下面这个例子,其中,在第一线,我更换intblock直观的回报语法:

void (^ )(void) (^myBlock)(void (^)(void));          // Syntax we 'intuitively would use'
void (^         (^myBlock)(void (^)(void))  )(void); // Official syntax
Run Code Online (Sandbox Code Playgroud)

我不是百分之百确定我要说的是什么,但我怀疑这种奇怪语法的原因是编译器中的解析器不会混淆.第一个"直观"语法会使编译器认为我们有一个块没有参数返回void,剩下的字符将被视为语法错误.

在我看来,语法是你不会过多质疑的东西(你当然可以批评它),因为它是语言设计的一部分,我们必须遵循规则(由一些有希望的智能工程师设定)要编译的代码.