Local variables declared within the lexical scope of the block, which behave exactly like local variables in a function.
Each invocation of the block provides a new copy of that variable. These variables can in turn be usedconst
Or by-reference variables in blocks enclosed within the block.
The following rules apply to variables used in a block: global variables can be accessed, including static variables in the scope. (Here, the block has read and write permissions on global variables.) parameters passed in the block can be accessed (just like parameters in the function ). Stack (Automatic Memory Management) (non-static) variables in the scope are used as constants. Their values in the program are called by block expressions. In nested blocks, variables in the most recent scope are used. (In my understanding, nesting can only use the nearest one. PS: This section is actually a few words: the common variables in the block are read-only. The _ block variable in the scope provides reference, so it is variable. All changes are reflected in the scope, including other blocks defined in the same scope. For more details, see The _ block Storage Type. The local variables declared in the block. Their behavior is similar to the local variables in the function. Each call of block provides a new copy of the variable. These variables in the block scope can be constants or variables (referenced ).The following example extends strates the use of local non-static variables:
The following example illustrates the use of non-static local variable variables.
int x = 123; |
|
void (^printXAndY)(int) = ^(int y) { |
|
printf(%d %d, x, y); |
}; |
|
printXAndY(456); // prints: 123 456 |
As noted, trying to assign a new valuex
Within the block wowould result in an error:
It is worth noting that an error is returned if you try to assign a value to the block in the block.
int x = 123; |
|
void (^printXAndY)(int) = ^(int y) { |
|
x = x + y; // error |
printf(%d %d, x, y); |
}; |
To allow a variable to be changed within a block, you use__block
Storage type modifier-see The _ block Storage Type.
To allow variable modification in The block, you need to use The _ block Type Storage. For details, see The _ block Storage Type.
The _ block Storage Type (_ block Storage Type)You can specify that an imported variable be mutable-that is, read-write-by applying__block
Storage type modifier.__block
Storage is similar to, but mutually exclusive of,register
,auto
, Andstatic
Storage types for local variables.
__block
Variables live in storage that is shared between the lexical scope of the variable and all blocks and block copies declared or created within the variable's lexical scope. thus, the storage will keep ve the destruction of the stack frame if any copies of the blocks declared within the frame has ve beyond the end of the frame (for example, by being enqueued somewhere for later execution ). multiple blocks in a given lexical scope can simultaneously use a shared variable.
As an optimization, block storage starts out on the stack-just like blocks themselves do. If the block is copied usingBlock_copy
(Or in Objective-C when the block is sentcopy
), Variables are copied to the heap. Thus,The address of__block
Variable can change over time.
There are two further restrictions on__block
Variables: they cannot be variable length arrays, and cannot be structures that contain C99 variable-length arrays.
You can specify that an input variable is variable (readable or writable) by using the _ block storage type modifier. _ Block is very similar (but different from), the register, auto, stack, and Storage types of local variables. _ The storage range of block variables is the scope of the variables and the scope declared or created by copying all blocks and blocks. Therefore, if a block copy statement is in a framework that is not destroyed, the storage will not be destroyed when the stack memory is destroyed until the framework ends (for example, is scheduled to somewhere and executed later ). Multiple blocks in the same scope can use one variable together. As an optimization, block Storage starts from the stack-just as they are doing it themselves. If the block uses Block_copy (or Objective-C, when the block sends a copy), the variable is copied to the heap (manual memory management ). In this way, the address of the _ block variable can be changed at any time. There are two further constraints on _ block variables: they cannot be a variable-length array or a structure containing the C99 array.
The following example extends strates use of__block
Variable:
The following example shows how to use the _ block variable.
__block int x = 123; // x lives in block storage |
|
void (^printXAndY)(int) = ^(int y) { |
|
x = x + y; |
printf(%d %d, x, y); |
}; |
printXAndY(456); // prints: 579 456 |
// x is now 579 |
The following example shows the interaction of blocks with several types of variables:
This example shows the interaction between several types of blocks.
extern NSInteger CounterGlobal; |
static NSInteger CounterStatic; |
|
{ |
NSInteger localCounter = 42; |
__block char localCharacter; |
|
void (^aBlock)(void) = ^(void) { |
++CounterGlobal; |
++CounterStatic; |
CounterGlobal = localCounter; // localCounter fixed at block creation |
localCharacter = 'a'; // sets localCharacter in enclosing scope |
}; |
|
++localCounter; // unseen by the block |
localCharacter = 'b'; |
|
aBlock(); // execute the block |
// localCharacter now 'a' |
} |
Object and Block Variables (Object and block variable)
Blocks provide support for Objective-C and C ++ objects, and other blocks, as variables.
A block can be used as a variable. It supports Objective-C and C ++ objects and other blocks.
Objective-C Objects (Objective-C object)When a block is copied, it creates strong references to object variables used within the block. If you use a block within the implementation of a method:
If you access an instance variable by reference, a strong reference is madeself
;
If you access an instance variable by value, a strong reference is made to the variable.
When a block is copied, it creates a strong reference to the object variables used in the block. If you implement a method in the block: If you access an instance variable by referencing, a strong reference is created for self. If you access an instance variable through the value, a strong reference is created for the variable.The following examples implements strate the two different situations:
The following example shows different situations.
dispatch_async(queue, ^{ |
// instanceVariable is used by reference, a strong reference is made to self |
doSomethingWithObject(instanceVariable); |
}); |
|
|
id localVariable = instanceVariable; |
dispatch_async(queue, ^{ |
/* |
localVariable is used by value, a strong reference is made to localVariable |
(and not to self). |
*/ |
doSomethingWithObject(localVariable); |
}); |
To override this behavior for a special object variable, you can mark it with__block
Storage type modifier.
By Rewriting a specific object variable, you can use the _ block storage type modifier to mark it.
C ++ Objects (C ++ object)In general you can use C ++ objects within a block. Within a member function, references to member variables and functions are via an implicitly importedthis
Pointer and thus appear mutable. There are two considerations that apply if a block is copied:
If you have__block
Storage class for what wocould have been a stack-based C ++ object, then the usualcopy
Constructor is used.
If you use any other C ++ stack-based object from within a block, it must haveconst copy
Constructor. The C ++ object is then copied using that constructor.
Generally, you can use block in a C ++ object. In a member function, the reference to the member variables and functions is implemented through a concealed this pointer, and then a variable occurs. If a block applies for copying, there are two possible reasons: If you have a stack-based C ++ object that contains the _ block Storage Class, the common constructor is used in this case. If you use other stack-based C ++ objects in a block, you must use the common copy constructor. The constructor used to copy the C ++ object.