【问题标题】:Alternative syntax to __block?__block 的替代语法?
【发布时间】:2013-06-04 00:56:20
【问题描述】:

我对@9​​87654322@ 变量的语法有疑问。我知道您可以在范围内的变量上使用__block,因此它在块内不是只读的。然而,在apple docs 的一个地方,我看到了另一种选择:

"定义范围内的变量在块中使用时默认为只读。如果需要更改此类变量的值,可以使用特殊语法:

int count = 0;
float cumulativeValue = 0.0;
UpdateElements( a, N, ^(float element){
    |count, cumulativeValue|
    float value = factor * element;
    ++count;
    cumulativeValue += value;
    return value;
} );

在这个例子中,count和cumulativeValue在块内部被修改,所以它们被包含在块作用域开头的逗号分隔的共享变量列表中。

这种语法看起来更简洁,我假设您可以修改未声明但仍在范围内的变量。但是,我在其他任何地方都没有看到过这种情况,并且 xCode 编译器不喜欢我的基本块。这是合法的语法吗?

【问题讨论】:

    标签: objective-c objective-c-blocks


    【解决方案1】:

    哇。好久没看到这个语法了。

    这是在开发块时探索的各种句法结构之一。它最终被拒绝了,因为它在声明意图时过于不精确,并且由此产生的行为会令人困惑。

    考虑一个包含三个块的作用域,其中两个通过|a| 将变量声明为可读写。无法从作用域顶部的 int a = 5; 声明中得知该变量的值在某些块的作用域中是可读写的。

    同样,它会使编译器的实现变得更加困难。 C 中的传统是变量存储类型在声明时是固定的。支持这种语法会打破这种期望。

    因此,决定使用类似于volatilestatic 的存储类型修饰符。使用__block 主要是因为__ 前缀大大减少了添加裸关键字会破坏的代码量。

    感谢您提出这个问题。提交了错误,该文档最终将被修复和/或删除。

    【讨论】:

    • 非常有趣!感谢您的历史
    • 那么,您知道为什么在您正式确定语法之前就编写了文档吗?
    • 如果文档人员无法弄清楚如何连贯地解释某事,这肯定表明设计存在严重缺陷,因此他们在设计过程的早期就参与了。该文档最初可能是为首次宣布 Blocks 的 WWDC 制作的。
    • 这与 C++ lambda 表达式的“捕获列表”语法相差不远(或者至少可以在不破坏事物的情况下移向该语法)。由于隐式块复制行为(如隐式自我保留)而出现的各种错误,我有点难过这种语法没有成功。你认为它比 C++ 中更明确的语法表现得更好吗?还是我误读了相似性?根据我的经验,知道块在块的点捕获什么比在声明点知道更重要。
    【解决方案2】:

    该 | |语法受到 Smalltalk 的启发,当然,术语“块”也是如此。

    正如 bbum 指出的那样,标记 decl 站点更诚实。非块使用,并且在建模时更符合 C,因为它最终作为一个新的 (C) 对象“持续时间”。

    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1451.pdf

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-04
      • 2013-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-18
      • 1970-01-01
      相关资源
      最近更新 更多