The code to be encapsulated is written in the braces following the parentheses, and the code can use parameters in the parentheses.The following is a code encapsulation process for finding the sum of two numbers.
typedef int (^BlockType)(int a,int b);BlockType varBlock;varBlock = ^(int a,int b){return a+b;};
Save codevarBlock
You can use this variable to call the code.
Int a = 4; int B = 6; int sum = varBlock (a, B); NSLog (@ "sum = % d", sum); // The output result is 10.
Block variables can also be assigned values to variables of the same type.
BlockType varBlockTemp; varBlockTemp = varBlock; int sum = varBlockTemp (1, 2); NSLog (@ "sum = % d", sum); // The output result is 3.
Pass a piece of code as a variable. The Block feature greatly facilitates subsequent coding.
3. Impact of Block variables on the scope of common variablesWhen code is encapsulated using Block objects, we need to clearly discuss a key issue, that is, the impact of Block variables on the scope of common variables.
This problem is solved through a simple case. See the following code:
Main () {int a = 1; {a = 2;} // the output value of a here is 2} // It is beyond the scope of variable, discussing the value of a is meaningless .}
This code is very simple. It uses a large extension to indicate the scope of the variable. Let's look at the following code:
typedef void (^ BlockType)(void);BlockType var;void fun1(){ int a = 10; var = ^(){NSLog(@"a = %d",a)};}void fun2(){ var();}main(){ fun1(); fun2();}
Call in the fun2 Functionvar
The variable is saved in fun1.var
Variable code, and the variables used in the codea
It is also a local variable in fun1.
Variables in normal statea
The scope of the function is in braces of the fun1 function. Used outside function bracesa
Is meaningless.
But in this case, variablesa
Block Variablevar
Used, sovar
The variable copies a, that is, the we use in the var code is actually a copy of.
Let's look at the following code:
typedef void (^ BlockType)(void);BlockType var;void fun1(){ int a = 10; var = ^(){NSLog(@"a = %d",a)}; a = 20;}void fun2(){ var();}main(){ fun1(); fun2();}
The output of this Code is the same as that of the previous Code. It does not change the value of a in the block because the value of a in the fun1 function changes. The reason is that when Block variables use local variables, they perform a copy operation on the local variables, and the code stored in the block variables uses a copy of the local variables.
However, in some special cases, we need to change the local variables to cause code changes in block variables. At this time, we need to use block panoramic variables.
Block panoramic variables pass through:__block
.
typedef void (^ BlockType)(void);BlockType var;void fun1(){ __block int a = 10; var = ^(){NSLog(@"a = %d",a)}; a = 20;}void fun2(){ var();}main(){ fun1(); fun2();}
In the code above, variable a in fun1 is modified by the block panorama variable identifier, that is, variable a becomes a block panorama variable.
The function is to use the variable when the block encapsulates the code. The copy operation is not performed, which means that the local variable a is the same variable as the variable in the block code. Therefore, the running result of the current Code is a = 20.
4. Block callback Interface UsageThe essence of callback is that the control Feedback its own information. In object-oriented programming, the control needs to call a method to feedback its own information, and the method must be subordinate to an object. Therefore, two parameters must be set for the previous callback interface, One Feedback object and one feedback method.
- In the target action, the feedback object is target, the feedback method is action, and a SEL type variable.
- In the delegate callback, the feedback object is delegate, and the feedback method is the method declared in the component protocol.
In Block callback, because the Block mechanism can directly encapsulate code as a variable, and this variable can be passed as a parameter. With this mechanism, the component can save this code and call this Code directly when an event is triggered, without the need to set feedback objects and feedback methods.
Here we still use the previous switch as an example:
typedef enum : NSUInteger { SwitchStateOff,//default SwitchStateOn,} SwitchState;typedef void(^SBlockType)(SwitchState state);@interface SwitchB : NSObject@property(nonatomic,assign,readonly)SwitchState currentState;@property(nonatomic,strong)SBlockType changeStateBlockHandle;@end
DeclaredchangeStateBlockHandle
The property is to save the callback code. Set the callback. You only need to assign a value to this attribute.
@ Interface Room: NSObject @ property (strong, nonatomic) Light * lightA; @ property (strong, nonatomic) SwitchB * s; @ end @ implementation Room-(instancetype) init {self = [super init]; if (self) {self. lightA = [[Light alloc] init]; self. s = [[SwitchB alloc] init]; _ weak _ block Room * copy_self = self; // breaks the strong reference loop. The subsequent sections will show self. s. changeStateBlockHandle = ^ (SwitchState state) {if (state = SwitchStateOff) {[self. lightA turnOff];} else {[self. lightA turnOn] ;};}return self ;}@ end
When the status of the switch changes, the switch must report its status to the user. When using the Block callback interface, you need to encapsulate the callback Code directly and assign the value to the Block type attribute of the component response. When the status changes, the encapsulated code is called by the component.