[iOS] Retain cycle in Blocks.

December 29, 2015

As promise, I will return with new post about Retain cycle in Blocks. But first, let’s take a bit look at this in case you guy have missed this valuable news. So now you guys all know about Retain Cycles, but how are they and how they impact to blocks, this post will lead you out.

Blocks?

This post requires some experiences with Blocks, but question is: What is Block? Well, that’s a good question. In my opinion, Block is a very cool thing that Apple supply to developers from iOS 4.0 and later, with a lot of amazing things that it can facilitate:

You can use blocks to compose function expressions that can be passed to API, optionally stored, and used by multiple threads. Blocks are particularly useful as a callback because the block carries both the code to be executed on callback and the data needed during that execution

Retain cycle in Blocks

The easiest way is jump right into example. I have created one, in ViewController.m I implemented:

#import "ViewController.h"

typedef void(^CustomBlock)(void);

@interface ViewController (){
    CustomBlock myCustomBlock;
}

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    myCustomBlock = ^{
        NSLog(@"This is a block.");
    };
}

There is nothing wrong with that. But let’s add a line to change backgroundColor of self.view, retain cycle alert is shown right way.

But why? Well, when I created a private variable CustomBlock myCustomBlock, the ViewController holded a strong reference (by default) to myCustomBlock, and into the block, I called self.view.backgroundColor to set, now the myCustomBlock holded a strong reference back to self. This made Retain cycle as previous post’s explaination.

Solutions

The solution in this case implies defining a weak version of self and sending that weak reference to the closure or block

__weak typeof(self) weakSelf = self;
    myCustomBlock = ^{
        NSLog(@"This is a block.");
        weakSelf.view.backgroundColor = [UIColor redColor];
    };

But in case you’re not sure the weakSelf can live all the long way of block or closure, just simply assign a strong referent from the begging of block and use it.

__weak typeof(self) weakSelf = self;
    myCustomBlock = ^{
        __strong typeof(weakSelf) strongSelf = weakSelf;
        NSLog(@"This is a block.");
        strongSelf.view.backgroundColor = [UIColor redColor];
    };

So hope you guys have some understanding for this, and have exp for solve this and know why.

Happy coding.