2

I think I understand how simple retain cycles are create but I don't fully understand more complicated situations.

Here is code that would cause a retain cycle. (right?)

[self.dataController loadInitialWithCompletion:^(BOOL dataChanged) {
    self.loading = NO;
}];

To avoid that retain cycle I would create a weak reference to self:

__weak typeof(self) welf = self;
[self.dataController loadInitialWithCompletion:^(BOOL dataChanged) {
    welf.loading = NO;
}];

I hope I'm correct so far.

Here's where it gets interesting. I have a method that calculates and caches text heights and then calls reloadData on a tableView. That method executes asynchronously and calls it's completionBlock (on the mainThread) when it's finished.

 __weak typeof(self) welf = self;
[self.dataController loadInitialWithCompletion:^(BOOL dataChanged) {
    [welf relayoutWithCompletion:^(CGPoint offsetBeforeReload) {
        welf.loading = NO;

        if (dataChanged) {
            [welf save];
        }

    }];
}];

Will this code cause a retain cycle because welf captures itself in the completionBlock for relayoutWithCompletion:? Am I correct in thinking that because welf is a weak reference I will avoid a retain cycle?

What if I took it a step further?

 __weak typeof(self) welf = self;
[self.dataController loadInitialWithCompletion:^(BOOL dataChanged) {
    [welf relayoutWithCompletion:^(CGPoint offsetBeforeReload) {

        if (offsetBeforeReload.y > 64) {
            [welf scrollToPoint:offsetBeforeReload completion:^{
                welf.loading = NO;
                [welf save];

            }];
        }

    }];
}];

It's welf all the way down...

Shawn Throop
  • 1,281
  • 1
  • 13
  • 28
  • I think these questions are similar but not the same, what about welf within welf thing? I don't store my blocks as properties etc. – Shawn Throop Apr 25 '14 at 20:26
  • If blocks are not stored as properties then it would be released after completion and retain cycle will be destroyed even if you use `self` in blocks (without weak self). – Vlad Papko Apr 25 '14 at 20:36
  • @Visput So my very first example won't cause a retain cycle? – Shawn Throop Apr 25 '14 at 20:40
  • If completion block is never stored (for example by property in dataController) then No. If to say more formally: it is retain cycle but it would be destroyed at the moment when completion block finished. So it's normal situation, it doesn't result to memory leak. – Vlad Papko Apr 25 '14 at 20:48

1 Answers1

2

No. Your weakSelf is a weak reference. Weak references do not cause retain cycles. That's the reason for using weak.

Duncan C
  • 128,072
  • 22
  • 173
  • 272