Storage location & memory management of block blocks in iOS

I. Introduction:

 Block is a powerful feature in Objective-C. Block can be regarded as the realization of closure function in OC. In essence, Block is also an object~

 

2. Memory allocation area:

The main memory allocation areas in OC: including stack area, heap area, constant area, global static area, text area (code area)

 

Memory allocation area

Stack area: Store function parameter values, local variables, function return addresses, etc. Every time we call a function, we will perform a stack operation (you will see a bunch of function call stacks in the left panel of XCode). It is characterized by high access efficiency and continuous access structure, but the space is small. There is an address space for the system to allocate and manage the stack by itself.

Heap area: This is the memory area that we developers need to focus on, because memory management usually comes from this area. The effect triggered by malloc, alloc, copy (deep copy), new and other methods is to allocate memory in the heap area. In the ARC environment, the system helps us manage the memory allocation and release of this area based on the reference count of the object, but we must always pay attention to the memory usage in this area; and in the MRC environment, developers need to be constantly Pay attention to the memory usage in this area, otherwise you know the consequences~

Static area: This area is actually subdivided into data area and BSS area. The data area stores static variables and global variables that have been initialized, while the BSS area stores static variables and global variables that have not been initialized, and the system is responsible for release and allocation.

Constant area: store constants, released and allocated by the system.

Code area (text area): store function body code.

 

3. Three categories of Block:

Block in the global area: __NSGlobalBlock__;

Block in the stack area: __NSStackBlock__;

Block in the heap area: __NSMallocBlock__;

1、__NSGlobalBlock__:

When we declare a block, if the block does not capture external variables, then the block is located in the global area. At this time, the retain, copy, and release operations of NSGlobalBlock are invalid. This is true in both ARC and MRC environments.

 

As shown in the figure, declare and define a block in the global area

2 __ __NSStackBlock__ :

  Someone may ask here, you rarely encounter blocks located in the stack area when programming, why? Because in the ARC environment, when we declare and define a block, and no additional modifiers are added to the block (the default is __strong modifier), if the block captures external variables, there is essentially a block from __NSStackBlock__ The process of transitioning to __NSMallocBlock__ is just the system helping us complete the copy operation, migrating the block in the stack area to the heap area, and extending the life cycle of the block. For the stack block, the stack block will be reclaimed when the function exits.

   Then when will __NSStackBlock__ appear in the ARC environment ? If we use the __weak or __unsafe__unretained modifiers when declaring a block, the system will not do the copy operation for us and will not migrate it to the heap area. Let's experiment:

 

As shown in the figure above, myBlock1 modified by __weak captures the external variable n and becomes a block in the stack area

 

In the default modifier environment, the block that captures external variables is located in the heap area

We can manually execute the copy method to verify the implicit conversion done by the system for us:

 

As shown in the figure, after manually executing the copy method, the block is migrated to the heap area

3、__NSMallocBlock__:

In the MRC environment, we need to manually call the copy method to migrate the block to the heap area. In the ARC environment, the __strong modified (default) block will be located in the heap area as long as it captures external variables. NSMallocBlock supports retain and release. The reference count will be +1 or -1. Declare and define the block located in the heap area as shown in the figure above.

 

Four, block access to different types of external variables:

1. As we all know, for the external variables captured by the block, the block defaults to copy it to its data structure to achieve access. Therefore, the block cannot modify the captured common external variables. We need to change the memory address of the external variable, that is, use the __block modifier to migrate the memory address of the pointer of the external variable in the stack to the heap area. Why is it designed like this? Let's quote a sentence from @ChenYiLong:

Apple’s design in this way should take into account the particularity of blocks. Blocks also belong to the category of "functions". Variables entering blocks actually have changed their scope. When switching between several scopes, if such restrictions are not added, the maintainability of variables will be greatly reduced. For another example, I want to declare a variable with the same name as an external variable in the block. Is it allowed or not allowed? Only with such restrictions can such a scenario be realized. So the stack area becomes a red light area, and the stack area becomes a green light area.

Therefore, the fundamental operation of the __block modifier is to change the memory address of an external variable, not simply to make the write operation effective.

2. In addition, if the external variable captured by the block is modified with static or the external variable is declared as a global variable, then the block can directly modify the external variable, because the address of the global variable or static variable in the memory is fixed (stored In the static area above), when the Block reads the value of the variable, it reads it directly from the memory where it is located, and obtains the latest value instead of the constant copied at the time of definition.

 

As shown in the figure above, blocks that capture static variables and global variables can directly modify their values. It should be noted that although the block captures external variables at this time, it is still a block located in the global area.




Reference link: https://www.jianshu.com/p/9c67b7716723

Guess you like

Origin blog.csdn.net/wangletiancsdn/article/details/99677530