33

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

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

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 编译器不喜欢我的基本块。这是合法的语法吗?

4

2 回答 2

45

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

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

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

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

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

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

于 2013-06-07T16:54:57.143 回答
5

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

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

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

于 2013-06-08T00:36:04.927 回答