update record
time | Revision |
---|---|
April 12, 2020 | First draft |
Foreword
Recently, I re-read "Objective-C advanced programming iOS and OS X multithreading and memory management" carefully. When I read the 2.2 Blocks mode chapter, I saw that automatic variables were intercepted in the Block and reassigned. Compilation error for "Missing __block modifier". This caused me to think a little bit. Here I describe my thinking.
Thinking
An example from the book
Use the object in the block
id array = [[NSMutableArray alloc] init];
void (^blk)(void) = ^{
id obj = [[NSObject alloc] init];
[array addObject:obj];
};
- The above code is no problem
Reassign objects in block
id array = [[NSMutableArray alloc] init];
void (^blk)(void) = ^{
array = [[NSMutableArray alloc] init];
};
- 编译报错:Variable is not assignable (missing__block type specifier)
- Many reference materials on the Internet say that adding the __block modifier to the variable can solve the problem. But they did n’t talk about the depth of the problem
Bottom thinking
- Referring to the implementation of Blocks in the subsequent chapters of "Objective-C Advanced Programming iOS and OS X Multithreading and Memory Management", we can know that the structure generated by Blocks will capture the variables used.
- Memory indicator
- For local variables, Blocks captures the value of this local variable by default (that is, MemoryObj), which can be modified by the content at the address of MemroyObj (essentially using the C language * operator)
- When the __block specifier is added, Blocks captures the memory address of this local variable, that is, the Memroy value (using the & operation in C language to obtain the address of a variable), so that Blocks can pass the data on Memory internally. Modify (* memroy = xxx), and can affect the outside of Blocks.
- The local variables that are not modified with __block are captured inside Blocks, and even if they are modified, it does not make any sense (the outside is not affected), so the compiler designed this compilation error at the beginning to avoid unpredictable bugs.