什么时候不在Objective-C中使用__block?

时间:2013-02-07 19:05:28

标签: ios objective-c objective-c-blocks

使用块时,为什么某些变量需要__block,而其他变量(如函数参数)则不需要?

2 个答案:

答案 0 :(得分:24)

这个问题的确是以错误的方式表达的。它不是“我什么时候需要__block?”,它是“__block做什么?”。一旦你了解它的作用,就可以告诉你何时需要它。

通常,当一个块捕获一个变量时(当一个块引用一个外部变量时就会发生捕获),它会创建一个变量的副本(请注意,在对象的情况下,它会创建一个指针的副本< / em>不是对象本身),如果它是一个对象,则保留它。

这意味着使用正常行为,您无法使用块来更改块外的值。此代码无效,例如:

int x = 5;
void(^block)() = ^{ x = 10; };

__block限定符进行了两处更改:最重要的是,它告诉编译器块应该直接捕获它,而不是复制。这意味着您可以更新块外的变量值。不太重要,但仍然非常相关,当不使用ARC时,它告诉编译器不要保留捕获的对象。

答案 1 :(得分:14)

代码块可以访问声明块的范围内的任何变量。但是,在块的范围之外声明的任何变量/对象在块内是不可变的。你可以阅读它,但不能改变它。在对象的声明中设置__block标志允许在块的范围内更改它。

编辑:这是一个例子:

NSString *myString = @"hello";
dispatch_sync(dispatch_get_main_queue(), ^{
    myString = @"hello world";
});

这不起作用,您将收到错误消息。

__block NSString *myString = @"hello";
dispatch_sync(dispatch_get_main_queue(), ^{
    myString = @"hello world";
});

问题解决了!