For the common application of blocks, the following classic problems are listed from the bottom up.

  • Block global and automatic variables;
  • Block variable reference;

Block internal modification of external variables

How does myBlock change age to 20?

int age = 10;
void(^myBlock)(void) = ^{

    NSLog(@"age--%d",age);
};
 myBlock();
Copy the code

Add static to the age variable, so that myBlock’s internal captured member variable is int *age, and the captured memory address can be passed to modify the age value directly. The structure of myBlock is as follows:

struct __main_block_impl_0{ struct __block_impl; struct __block_des; int * age; / / pointer}Copy the code

2. Make age a global variable that blocks can access and use. Global variables any function can be called anywhere.

Accessorize with the __block keyword. Its underlying principle: __block encapsulates age as a __Block_byref_age_0 object with an internal __forwarding pointer to itself, Age ->__forwarding->age ->age

The essential structure of block is as follows:

struct __main_block_impl_0{ ... __Block_byref_age_0 *age; // Essence is object}Copy the code

__Block_byref_age_0 has the following essential structure:

struct __Block_byref_age_0{
    void * __isa;
    __Block_byref_age_0 *__forwarding;
    int __flags;
    int __size;
    int age;
}
Copy the code

Block variable references.

WSTObjct * wstObj = [[WSTObjct alloc] init]; __weak WSTObjct * blockWstObj = wstObj; Dispatch_after (dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{NSLog(@)"1 -- -- -- -- -- - % @",blockWstObj);
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            
            NSLog(@"2 -- -- -- -- -- - % @",wstObj);
        });
    });
    
    NSLog(@"touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event");
    
Copy the code

When the WSTObject is destroyed, we print dealloc

@implementation WSTObjct

- (void)dealloc
{
    NSLog(@"WSTObjct object destruction");
}

@end
Copy the code

How many seconds after the WSTObjct object is destroyed after executing the code is printed?

Answer: Print after three seconds, as shown below;

First, wstObj is a local variable, and block captures the variable to __main_block_impl. The compiler will notice that the wstObj in the second dispatch_after is strongly referenced to the block, so the wstObj is destroyed when the block is destroyed.