Objective-C -- Block, objective-cblock
In fact, the OC Block function is similar to the function pointer in C language and the closure in js. You can operate a code block as a variable with its own variables and scopes.
Let's take a brief look at the Block syntax and possible problems:
Block Syntax:
The block syntax is relatively loose and can be omitted in many parts. In general, we need the following parts to implement a block:
^ Return value type parameter list expression
For example
^ Int (int count) {return count + 1 ;}; // the return value is int. The int expression is count + 1. ^ void (void) {NSLog (@ "void") ;}; // the return value is the void parameter. The void expression is NSLog (@ "void ");
It can be seen that the syntax is relatively simple, and the return value type can be omitted. Then the above two blocks will change.
^(int count){return count+1;}; ^(void){NSLog(@"void");};
If the parameter is not applicable, the return value list can be omitted.
^(int count){return count+1;}; ^{NSLog(@"void");};
Block type variables
The Blcok type variables can accept the corresponding Block. In the above example, the two blocks require the following two types of Block variables to receive
int (^intBlock)(int) = ^(int count){return count+1;}; void (^voidBlock)(void) = ^{NSLog(@"void");};
In the preceding example, the variable definition format is displayed.
Return Value Type (^ variable name) (return value type)
If this definition method is difficult, you can use typedef to simplify the definition method.
typedef int (^typedefBlock) (int); typedefBlock block = ^(int count){return count+1;};
Intercepted variable value
Block, you can use the value of the variable before calling the Block, such
int a = 5; int (^intBlock)(int) = ^(int count){return count+a;}; NSLog(@"%d",intBlock(5)); 2015-08-02 17:25:53.393 Dispatch[9970:3096937] 10
The output value is 10, indicating that intBlock intercepts the value of variable.
However, if we want to modify the value of a, an error may occur. You can try it yourself.
To modify a variable, you must add the _ block modifier before it. This indicates that the variable can be modified in the block.
__block int a = 5; int (^intBlock)(int) = ^(int count){a = 3; return count+a;}; NSLog(@"%d",intBlock(5)); 2015-08-02 17:33:11.629 Dispatch[10118:3136172] 8
The output value is 8, indicating that it has been modified.
Similarly, for an OC object, if you call a method to use this variable, you must add the _ block modifier to assign values to the variable.
Block loop reference
When a circular reference condition occurs, the object holds the member attributes of the Block and uses self in the Block. This will cause mutual reference between blocks and objects, and mutual release will not be possible, resulting in Memory leakage.
@interface ViewController (){ voidBlock _voidBlock;}- (void)viewDidLoad { [super viewDidLoad]; // __block int a = 5; _voidBlock = ^{NSLog(@"%@",self);}; _voidBlock();}
In this way, the strong reference of self will be prompted to be used in the Block.
In addition, if we use the member attribute in the Block, it will also cause memory leakage. Because the Member attribute is the object pointed to by the self pointer, or the self is held in the Block.
_ Weak
In order to avoid this situation, let's modify it a little later in the above example.
- (void)viewDidLoad { [super viewDidLoad]; // __block int a = 5; __weak ViewController *temp = self; _voidBlock = ^{NSLog(@"%@",temp);}; _voidBlock();}
This situation can be avoided by using weak reference objects.
Then, use _ block to avoid loops.
- (void)viewDidLoad { [super viewDidLoad]; // __block int a = 5; __block ViewController *temp = self; _voidBlock = ^{NSLog(@"%@",temp); temp = nil;}; _voidBlock();}
Note that the Block must be called to execute the Block code. If the Block code is not executed, memory leakage may occur.