编译器不会将每个变量都视为__block变量的原因是什么?

时间:2011-10-31 02:49:24

标签: objective-c xcode objective-c-blocks clang

编译器(特别是Xcode使用的编译器)没有将每个变量视为__block变量的性能提升有哪些?我想有必要有一些东西,我怀疑在__block变量的构思过程中,我决定

 __block SelfClass * blockSelf = self;

语法很方便。

2 个答案:

答案 0 :(得分:4)

块的目标是使其尽可能自动且透明,以使用具有最小语法的块并使它们“正常工作”。

非___块变量,作为默认值,更符合块所代表的“闭包”的概念。在执行通过块声明时,块会快照块中引用的所有变量的状态。这包括复制内存/状态和保留块中捕获的任何Objective-C对象引用。

__block有效地打破了块内状态的封装。非常有用,但需要程序员手动管理对象引用。

即。非___块变量“只是工作”更常见的__block变量,因此,默认行为是倾向于“正常工作”。

实际上,在一个区块内捕获状态的成本通常很低。对应用程序性能的可衡量影响通常很少,并且通常表明架构问题更为深刻。


如果通过:

 __block SelfClass * blockSelf = self;

您指的是Blocks和ARC的交叉产品吗?是的,这有点不幸。但编译器也警告你需要注意一个非常现实的问题。但是,更清洁的解决方案显然更可取。

答案 1 :(得分:0)

因为__block可能会在堆栈破坏后继续存在。只有使用c ++范围的变量才能注意到这一点:

{
    __block shared_ptr<A> ptr = make_shared(new A);
    self.some_block = ^(void){};
} // ptr will not be deleted until the block is destructed
{
   shared_ptr<A> ptr = make_shared(new A);
    self.some_block = ^(void){};
} // ptr will be deleted here

垃圾收集也很明显,但它更不明显,难以作为例子。