Block classification

  1. NSGlobalBlock(Global block)
  • The global area
  • External variables are not used inside blocks, or only static and global variables are used

Code:

static int a = 0;
void (^block)(void) = ^{
 NSLog(@" %d",a);
};
Copy the code
  1. NSMallocBlock(Heap block)
  • The heap area
  • Use variables or OC attributes inside blocks and assign values to strongly referenced or Copy trim variables

Code:

int a = 0;
void (^block)(void) = ^{
 NSLog(@" %d",a);
};
Copy the code
  1. NSStackBlock(Stack block)
  • The stack area
  • Use variables or OC attributes inside blocks, but cannot be assigned to strong references or Copy trim variables, known as weak reference modifiers.

Code:

int a = 10;
void ( __weak ^block)(void) = ^{
NSLog(@" %d",a);
};
Copy the code

Block loop reference

  • Why do circular references occur?

Normal release of A and B:

A strong holds B, B strong holds A, cannot release

  • Block loop references the case

Circular references occur when we use the code above. The compiler will also say so how do you solve that?

  • Use weak references __weak

But there is a problem, when we block is a time consuming operation and we exit the page, we will find that the name is empty. Since the controller has been released at this time, how to solve this problem

  • Use weak references __weak + __strong

At this point, there’s this application relationshipself->block->weaSelf->strongSelf->SelfBecause StrongSelf is a temporary variable, it needs to be destroyed when the block completes. This breaks the cycle and avoids early release.

  • Hand release

self -> block -> vc -> selfWe can manually release through an intermediate variable, and when the block is done, set vc=nil to break the loop

  • Block mass participation

We know that OC methods have a self argument by default, and we can also pass in a block argument to avoid circular references.

Block Case Analysis

Case 1:

static ViewController *staticSelf_;
- (void)blockWeak_static {
// It is the same memory space
__weak typeof(self) weakSelf = **self**;
staticSelf_ = weakSelf;
// staticSelf_ -> weakSelf -> self
}
Copy the code

Does the above code create a loop? The answer is yes. StaticSelf_ -> weakSelf -> Self. StaticSelf_ is a global static variable that will not be released after exiting the interface. So self doesn’t release. So __weak doesn’t necessarily cause memory leaks.

Case 2:

The above code also produces a memory leak where the strongSelf is held by doStudent, causing the strongSelf to be unable to be released. self->weakSelf->strongSelft->doStudent->WeakSelf.