本文翻译自:What does the “__block” keyword mean?
What exactly does the __block
keyword in Objective-C mean? Objective-C中的__block
关键字究竟是什么意思? I know it allows you to modify variables within blocks, but I'd like to know... 我知道它允许你修改块内的变量,但我想知道......
- What exactly does it tell the compiler? 它究竟是什么告诉编译器的?
- Does it do anything else? 它还有什么用吗?
- If that's all it does then why is it needed in the first place? 如果就是这样,那么为什么首先需要呢?
- Is it in the docs anywhere? 是在任何地方的文档? (I can't find it). (我找不到)。
#1楼
参考:https://stackoom.com/question/Ti4V/block-关键字是什么意思
#2楼
hope this will help you 希望对你有帮助
let suppose we have a code like: 让我们假设我们有一个代码:
{
int stackVariable = 1;
blockName = ^()
{
stackVariable++;
}
}
it will give an error like "variable is not assignable" because the stack variable inside the block are by default immutable. 它会给出一个错误,例如“变量不可赋值”,因为块内的堆栈变量默认是不可变的。
adding __block(storage modifier) ahead of it declaration make it mutable inside the block ie __block int stackVariable=1;
在声明之前添加__block(存储修饰符)使其在块内__block int stackVariable=1;
可变,即__block int stackVariable=1;
#3楼
__block is a storage qualifier that can be used in two ways: __block是一个存储限定符,可以通过两种方式使用:
Marks that a variable lives in a storage that is shared between the lexical scope of the original variable and any blocks declared within that scope. 标记变量存在于原始变量的词法范围与该范围内声明的任何块之间共享的存储中。 And clang will generate a struct to represent this variable, and use this struct by reference(not by value). 并且clang将生成一个表示此变量的结构,并通过引用(而不是值)使用此结构。
In MRC, __block can be used to avoid retain object variables a block captures. 在MRC中, __block可用于避免块捕获保留对象变量。 Careful that this doesn't work for ARC. 小心这对ARC不起作用。 In ARC, you should use __weak instead. 在ARC中,您应该使用__weak 。
You can refer to apple doc for detailed information. 您可以参考apple doc获取详细信息。
#4楼
Normally when you don't use __block, the block will copy(retain) the variable, so even if you modify the variable, the block has access to the old object. 通常,当您不使用__block时,该块将复制(保留)该变量,因此即使您修改了该变量,该块也可以访问旧对象。
NSString* str = @"hello";
void (^theBlock)() = ^void() {
NSLog(@"%@", str);
};
str = @"how are you";
theBlock(); //prints @"hello"
In these 2 cases you need __block: 在这两种情况下,您需要__block:
1.If you want to modify the variable inside the block and expect it to be visible outside: 1.如果你想修改块内的变量并希望它在外面可见:
__block NSString* str = @"hello";
void (^theBlock)() = ^void() {
str = @"how are you";
};
theBlock();
NSLog(@"%@", str); //prints "how are you"
2.If you want to modify the variable after you have declared the block and you expect the block to see the change: 2.如果要在声明块后修改变量,并且希望块看到更改:
__block NSString* str = @"hello";
void (^theBlock)() = ^void() {
NSLog(@"%@", str);
};
str = @"how are you";
theBlock(); //prints "how are you"
#5楼
这意味着它是一个前缀的变量可以在一个块中使用。
#6楼
@bbum covers blocks in depth in a blog post and touches on the __block storage type. @bbum在博客文章中深入介绍了块,并触及__block存储类型。
__block is a distinct storage type __block是一种独特的存储类型
Just like static, auto, and volatile, __block is a storage type. 就像静态,自动和易失性一样,__block是一种存储类型。 It tells the compiler that the variable's storage is to be managed differently. 它告诉编译器变量的存储将以不同方式进行管理。
... ...
However, for __block variables, the block does not retain. 但是,对于__block变量,块不会保留。 It is up to you to retain and release, as needed. 您可以根据需要保留和释放。
... ...
As for use cases you will find __block
is sometimes used to avoid retain cycles since it does not retain the argument. 对于用例,您会发现__block
有时用于避免保留周期,因为它不保留参数。 A common example is using self. 一个常见的例子是使用self。
//Now using myself inside a block will not
//retain the value therefore breaking a
//possible retain cycle.
__block id myself = self;