首页 文章

理解复杂的块语法

提问于
浏览
11

我'm a beginner to Objective C and iOS development, but a 13-year .NET veteran. I'很难在心理上绘制以下声明,该声明来自Programming with Objective C指南:

void (^(^a)(void (^) (void))) (void) = ...

它用作为什么应该使用 typedef 定义块的示例,但我想了解我正在考虑的内容,以便首先更好地了解块定义语法 .

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

enter image description here

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

[return_val] (^[block_name]) ([block_args]) = ...

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

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

typedef void (^SimpleBlock) (void);
SimpleBlock (^complexBlock) (SimpleBlock) = ...

我只是想念如何 .

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

2 回答

  • 0

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

    void (^(^a)(void (^)(void)))(void)
    

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

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

    在此示例中,返回的块不带参数并返回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
    

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

    显然 typedefs 让它更容易阅读 .

    编辑:
    考虑这个例子,在第一行中,我使用直观的返回语法将 int 替换为 block

    void (^ )(void) (^myBlock)(void (^)(void));          // Syntax we 'intuitively would use'
    void (^         (^myBlock)(void (^)(void))  )(void); // Official syntax
    

    我想说,但我怀疑这种奇怪语法的原因是编译器中的解析器没有直观的'语法会让编译器认为我们有一个块没有参数返回void,剩下的就是字符将被视为语法错误 .

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

  • 10
    void (^(^a)(void (^) (void))) (void)
    

    将这些语法分解为几个部分:

    • a 是一个变量 .

    • 它可以像c指针"*"一样通过语法"^"解除引用: ^a .

    • (^a)(void (^) (void) 是一个名为 a 的块,并将块 (void (^) (void) 作为参数 .

    • 可以取消引用它的返回值以产生块信息: ^(^a)(void (^) (void)) . (并暗示返回值因此是一个块指针)

    • 此返回的块不带参数: (^(^a)(void (^) (void))) (void) .

    • 并且此返回的块不需要返回值: void (^(^a)(void (^) (void))) (void)

    所以,让我们说 (^a) (void (^) void) 不是 Meaning the name of my block, rather than being a straight string, is itself a block. . 块文字不一定是

    [return_val] (^[block_name]) ([block_args])
    

    编译器将把插入符号作为块后面的代码 .

相关问题