Block Memory Management 1

__block modifiers are doing things

We often need to modify external variables in the block, and when the value of the variable is passed, in the block where we can not be modified.

int age = 10; here we declare a variable of type default is auto.

void (^ block) (void) = ^ {age = 10;} This is wrong and can not be modified in the block in the external variables, block capture external variables, for topical variable auto type, is captured value, block where a just copy the value of a. We can go visit, but can not be modified

In view of this situation, we add a variable before __block modifiers, __ block int age = 10; so that we can achieve the purpose of modifying variables in a block.

However __block in the end did what played an object can be passed in the external value of the modified inside it? Below, the test code write section

__block modifying the underlying data type:

2304477-6346bb457227d6a1.png
Figure -01

Then use the terminal clang compiler to recompile our files into C ++ files

xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-8.0.0 main.m -o main-arm64-arc.cpp.

In the sandbox generates a main-arm64-arc.cpp file, the file system when compiling, compiled files are similar, but the details will be different in some places.

We can see in Figure -02 OC and the code corresponding to the piece, is __Block_byref_age_0 object declaration instead of int age. Then declare block where this variable red zone pass into it, calling __main_block_impl_0 (this structure is the block in the form of C ++, the underlying principle of the article block specific instructions) constructor returns a pointer to this structure. __main_block_impl_0 shown in Figure -03, there is a __Block_byref_age_0 members, followed by the __Block_byref_age_0 see what it was,

2304477-f7e21d77449f91d7.png
Figure -02

Our block structure in this package will keep the __block modified variable structure, this structure is what is it, as shown in Figure -04.

2304477-d6524cee3e7ce4db.png
Figure -03

This is what we __Block_byref_age_0 in the age variable on the outside.

2304477-71ece92041e4de1a.png
Figure -04

How to prove that age is the age out of it, we can simulate several structures of this document, strongly objects block transfer, if as said before, there was a strong turn of the block must have several properties on the map. The following code:

2304477-5496904aa9197f5f.png
Figure -05

Here indeed is the final print of the same address.

If __block modified object type of a variable, also generates two functions __main_block_desc_0 years, these two functions, copy is called when the block moved by the heap space stack space, disoise called when the block is destroyed.

Supplementary 1: __ main_block_impl_0 in variable __Block_byref_age_0 a structure member ARC environment is always under strong references in __Block_byref_age_0 structure, the outside come in if it is to capture the object will have strong and weak points of reference, is weak in the case of MRC It cited the case of MRC compiler environment, problem solving circular references on, you can use __block modifiers, can also solve the problem of circular references.


2304477-674c5878e307bed2.png
2304477-b495ac678bdded09.png

Supplement 2: function block in the block in the package, outside the access __block captured by the modified variable age -> __ forwarding-> age a form in which the age is the first __Block_byref_age_0 structure, pointing __ Forwarding __Block_byref_age_0 structure their own hands, and then through a pointer to itself access real age. Why not just through the structure age-> age it, because, in a function, block by default in the stack, but under the ARC environment, the system will default to blockcopy moved to the heap, and block structure in the variable or __block on the stack, __block variables on the stack __Block_byref_age_0 structure such access would be at risk in the heap, so broke __forwarding pointer, he is pointing to the heap of __Block_byref_age_0 structure, so, no matter __Block_byref_age_0 on the heap or on the stack, which pointers are pointing to the heap __forwarding __Block_byref_age_0 structures themselves.


2304477-7f03bb5347618f0f.png

Reproduced in: https: //www.jianshu.com/p/32ff9558bd7a

Guess you like

Origin blog.csdn.net/weixin_34259159/article/details/91166268