OC Block actually functions like C language function pointers, JS in the closure and so on. The code block acts as a variable, with its own variables and scopes.
Simply look at the syntax of block and the possible problems:
Block Syntax:
Block syntax is relatively loose, many parts can be omitted, the general implementation of a block we need to have the following parts
^ return value type parameter list expression
For example
^int (int count) {return count+1;}; // The return value for the int parameter is an int expression of count+1; ^void (void) {NSLog (@ "void");}; // The return value for void parameter void expression is NSLog (@ "void");
You can see that the syntax is relatively simple, and that the return value type can be omitted so that the above two blocks are changed
^ (int count) {return count+1;}; ^ (void) {NSLog (@ "void");};
If the parameter is not applicable, then the return value list can also be omitted
^ (int count) {return count+1;}; ^{nslog (@ "void");};
Block type variable
Blcok types of variables can accept the corresponding block, the above example two blocks will require the following two types of block type variables to receive
int (^intblock) (int) = ^ (int count) {return count+1;}; void (^voidblock) (void) = ^{nslog (@ "void");};
In the example above, you can see the variable definition format
return value type (^ variable name) (return value type)
If this definition is troublesome, you can use TypeDef to simplify the way you define it.
int (^typedefblock) (int); = ^ (int count) {return count+1;};
Intercept variable values
block, you can use the value of a variable before calling block, such as
int a = 5 ; int (^intblock) (int ) = ^ (int count) {return count+A;}; NSLog ( @ " %d , Intblock (5 2015 -08 - 02 17 : : 53.393 dispatch[9970 : 3096937 ] 10
You can see that the output is 10, indicating that Intblock intercepted the value of variable A.
But if we want to change the value of a, there will be an error and we can try it ourselves.
To modify the need to add the __block modifier before the variable, the variable can be modified in the block.
__blockintA =5; int(^intblock) (int) = ^(intCount) {a =3;returncount+A;}; NSLog (@"%d", Intblock (5)); -- ,- Geneva -: -:11.629dispatch[10118:3136172]8
The output is 8, the explanation has been modified by us.
Similarly, for an already OC object, if the calling method uses the variable, the assignment to the variable requires a __block modifier.
Block Circular Reference
A circular reference occurs when the object holds the member property of the block and uses self in the block. This results in a mutual reference between the block and the object, which cannot be freed from each other, creating a memory leak.
@interface Viewcontroller () { voidblock _voidblock;} -(void) viewdidload { [super viewdidload]; __block int a = 5; _voidblock = ^{nslog (@ "%@", self);}; _voidblock ();}
This compilation will prompt us to use the strong reference of self in block.
There is also a memory leak if we use member properties in the block. Because the member property is the object that the self pointer points to, or self is held in the block.
__weak
To prevent this from happening, let's change it slightly in the example above
-(void) viewdidload { [super Viewdidload]; // __block int a = 5; __weak Viewcontroller *temp = self ; = ^{nslog (@ "%@", temp);}; _voidblock ();}
Using weakly referenced objects can be a good escape from this situation.
Then there is the use of __block can also avoid circulation.
-(void) viewdidload { [super Viewdidload]; // __block int a = 5; __block Viewcontroller *temp = self ; = ^{nslog (@ "%@", temp); temp = nil;}; _voidblock ();}
Note that this must be called by the block, the block code is executed, if not executed or will cause a memory leak.
Objective-c--block