Why must modify the value of local variables in Block to be declared as __block type

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.

Guess you like

Origin www.cnblogs.com/HelloGreen/p/12684033.html