使用块时,为什么某些变量需要__block,而其他变量(如函数参数)则不需要?
答案 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";
});
问题解决了!