In the initial case:
The block itself, the __block modified variables, and the variables used inside the block are all in the stack.
The address of a __block modified variable is passed inside the block block as an argument (which is, for the time being, actually more complex). The external variables used by the block are copied to the inside of the block by the Const. That is, the external variable used by block is not related to the external variable itself.
After the Copy method
The method of being copied is still on the stack. But the block after the copy has been placed on the heap. At the same time the __block modified variable is moved to the heap, the original on the stack does not exist. A const copy of the block's external variables is also copied to the heap.
Once the block on the heap is copied again, only the reference count increases by 1, but the copy action is not re-made.
Retain operation
Because the retain has a return value. Retain requires that the address returned is the same as the address of the calling object. But the address of the block may be variable (especially from stack to heap), so it is useless to do a retain operation on the block. Nothing is going to be done!
Destroyed (or when memory is reclaimed)
Block blocks on the heap are destroyed before the stack is destroyed, such as calling release to destroy block blocks on heaps. Block blocks in the heap are destroyed when the reference count becomes 0. The __block modified variable is still in the heap, because the stack is used, and the block on the stack is used fast.
When the block blocks on the heap are later than the stack, the stack is cleared. Block blocks in the heap release memory when calling release to reduce the reference count to 0.
Block memory management for iOS