First, the simplest block
1, the simplest block structure
^{
NSLog(@"this is a block");
NSLog(@"this is a block");
NSLog(@"this is a block");
};
Copy the code
2. Block calls
^{
NSLog(@"this is a block");
NSLog(@"this is a block");
NSLog(@"this is a block"); } ();Copy the code
void (^block)(void) = ^{
NSLog(@"this is a block");
NSLog(@"this is a block");
NSLog(@"this is a block");
};
block();
Copy the code
2. The underlying structure of block
- Use terminal
cd
tomain.m
File folder and execute the following command line
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m
Copy the code
- The generated
main.cpp
Drag the file into the project and open it to see the compiled versionmain
Delta function, you can see thatblock
Definition and invocation of
- in
main.cpp
The following code can also be found in
- You can see
block
The underlying structure is__main_block_impl_0
The structure of the body block
The code block is also wrapped into a function__main_block_func_0
__main_block_impl_0
The first argument to__block_impl
The structure is as follows
- so
__main_block_impl_0
The structure can be viewed as follows, because the first member variable isisa
, soblock
The essence is aOC object
- Take a look at
main
Function will be createdblock
Object to delete the cast type, you can see the following
-
To create __main_block_IMPL_0, we pass in two arguments, the first of which is the address of the __main_block_func_0 function that encapsulates the block code block, __main_block_desc_0(0, __main_block_IMPL_0)
-
Then look at the __main_block_IMPL_0 constructor
- You can see
__main_block_func_0
The function address assigned to__block_impl
A member variable of a structureFuncPtr
.block
Is assigned to the second member variableDesc
Summary: The essence of a block is an OC object that encapsulates a function call and its environment
block
The call is made by findingimpl
In theFuncPtr
To get to the__main_block_func_0
The address of the function is then called and passed in at the same time__main_block_impl_0
The address of the
- The reason why we use it directly here
block->FuncPtr
Rather thanblock->impl.FuncPtr
Because,impl
isstruct __main_block_impl_0
The first member variable of, soimpl
The address andblock
Have the same address
- So you can pass
block
Pointer is used directlyFuncPtr
The underlying structure of a block with parameters
- When you define a block, you can pass in parameters
- Use terminal
cd
tomain.m
File folder and execute the following command line
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m
Copy the code
- The generated
main.cpp
Drag the file into the project and open it to see the compiled versionmain
Delta function, you can see thatblock
Definition and invocation of
- After deleting the type conversion, the code is called as follows
block
When introduced into the10
and20
4. Variable capture of block
- There are three main types of variables in OC, namely
Auto, static, global variables
, includingAuto and static
Modification isA local variable
- These three types of variables are captured differently by blocks when they are used
1. Auto variable capture (value capture)
- In OC, the variables that we define, by default, are
auto
Type, which is destroyed when it leaves scope - when
block
Variable capture is performed when external variables are used in
- Use terminal
cd
tomain.m
File folder and execute the following command line
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m
Copy the code
- The generated
main.cpp
Drag the file into the project and open it, and you can see the compiled block - You can find
__main_block_impl_0
There is one more member variable in the structureage
theage
Is based onmain
In the functionage
Generated member variables __main_block_impl_0
In theage
andmain
In the functionage
Are two independent variables
block
Used when calledage
is__main_block_impl_0
Is a member variable instead ofmain
In the functionage
- while
age
Is the value ofblock
Passed in when created
- So in the
main
In the delta function, if the delta function isblock
Modify the age value after definition in the callblock
When,age
The value of phi does not change
- The underlying structure is as follows
2. Static variable capture (pointer capture)
- There is code as follows to use
static
modifiedage
variable
- At the bottom of the
__main_block_impl_0
In theage
Type is a pointer typeint *
- To the instructions
static
A modified variable captures the address of the variable__main_block_impl_0
In the - At this time
main
Function, call__main_block_impl_0
Is passed to the constructor ofage
The address of the
- in
block
Call,__main_block_func_0
The function also passesage
Address access ofage
The value of the
- At this point, if
main
In the functionblock
Subsequent modifications to the definitionage
The value of, then inblock
Accessed by address inage
That’s the modified value
- The underlying call code is as follows
Use global variables in block (no capture)
- At this time
block
The underlying structure of,block
Did not captureage
“, but directly use
Summary: If a global variable is used in a block, the global variable is not captured in the block. When a block is called, the global variable is used directly, so the value of the global variable changes, and the value used in the block changes accordingly
- Modify the
age
Value in the callblock
As you can seeblock
The values printed in the
4. Block captures auto, static and global variables
Summary: In a block, if you use a local variable, that variable is captured. In a block, if you use a global variable, that variable is not captured, but used directly