Before introducing today’s blog, you should understand the three types of blocks, the variable capture mechanism of blocks, and which cases are NSmallcblocks. My previous blog has covered this very clearly, and I believe you will learn a lot from it.

Through this blog, you will learn:

__block it when the modifier, it is exactly how the underlying implementation.

First look at the following code:

Do you know why it’s wrong to change the value of a variable? C ++ = c++ = c++ = c++ = c++ = c++ = c++ = c++

xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main.cpp

Func_0 (func_0, func_0, func_0, func_0, func_0, func_0, func_0, func_0, func_0, func_0, func_0, func_0, func_0, func_0, func_0, func_0, func_0, func_0, func_0, func_0, func_0, func_0

If we add a static parameter to the argument, we won’t get an error! Please see below

Static *age *age *age *age *age *age

The key to the

Take a look at the following code, where I use __block as a modifier:

Why is it ok to use __block here? Let’s switch to c++ code to see the underlying implementation:

This is very clear, as soon as I decorate a variable with __block, I wrap the variable into an object, which is a structure. This is very clear, but I’ll explain why __forwarding is accessed later

Now LET me explain what *__forwarding is. Please take a look at the following, I deleted the extra code (you can compare the original delete the extra code, so that we can see it):

The following boxes I just removed the cast code are the same

The sizeof is the sizeof the current structure, and the bottom box, its own age, is passed to the second argument, &age, which is assigned to *__forwarding, so __Block_byre F_age_0 its address is *__forwarding, which is also very clear

GDblock block = GDblock block = GDblock block = GDblock block = GDblock block = GDblock block = GDblock block = ((void(*)())&__main_block_impl_0((void*)__main_block_func_0, &__main_block_desc_0_DATA, (__Block_byref_age_0 *)&age,570425344)); This is the code to look at the __main_block_impl_0 implementation to see the assignment.

Take a look at the following code:

Does it get an error? And the answer is no, because I’m not modifying it, I’m just using it.

The block stores the value of the structure’s memory address, and when it changes, it finds the structure’s memory address and changes the value

So far: it is clear why blocks can modify variables modified by __block modifiers

Conclusion:

1.__block can be used to solve the problem that the value of the auto variable cannot be changed inside the block

2.__block cannot modify a global variable or a static variable.

3. The compiler wraps __block as an object

Now the next thing that might confuse some of you a little bit is if I NSLog(@”%p” &age); What is the address of age? The following

Which age is this?

As follows:

Now let’s prove this problem, and this idea that I had in my previous blog, is to take the underlying implementation structure and use it

We can see that it’s not the address of the age stored in the block, it’s not the same value, and I can tell you that it’s the address of the age that is equal to 10 in the age block, if you look at the picture below, let me prove it

The first thing you need to know is that the address of the large age structure is the address of its first element, so 0x0000000101CB92A0 is the address of _ISA in the age structure. I want to be clear about this

So this is a very clear proof that this is really the value of the age in the age structure

I will continue my discussion of blocks in the following blog by introducing Block’s __block and other points of knowledge

If you find my writing helpful, please follow me and I will continue to update 😄