42

Suppose I already create a weak self using

__weak typeof(self) weakSelf = self;
[self doABlockOperation:^{
        ...
}];

Inside that block, if I nest another block:

[weakSelf doAnotherBlockOperation:^{
    [weakSelf doSomething];
}

will it create a retain cycle? Do I need to create another weak reference to the weakSelf?

__weak typeof(self) weakerSelf = weakSelf;
[weakSelf doAnotherBlockOperation:^{
    [weakerSelf doSomething];
}
Olcay Ertaş
  • 5,987
  • 8
  • 76
  • 112
Enzo Tran
  • 5,750
  • 6
  • 31
  • 36

2 Answers2

60

Your code will work fine: the weak reference will not cause a retain cycle as you explicitly instruct ARC not to increase the retainCount of your weak object. For best practice, however, you should create a strong reference of your object using the weak one. This won't create a retain cycle either as the strong pointer within the block will only exist until the block completes (it's only scope is the block itself).

__weak typeof(self) weakSelf = self;
[self doABlockOperation:^{
    __strong typeof(weakSelf) strongSelf = weakSelf;
    if (strongSelf) {
        ...
    }
}];
iwasrobbed
  • 46,496
  • 21
  • 150
  • 195
Gianluca Tranchedone
  • 3,598
  • 1
  • 18
  • 33
  • 1
    Can you detail a little more or give me some links about why I should create a strong reference to my object using the weak one? 1 or 2 practical cases would help a lot. Thanks. – Enzo Tran Jun 14 '13 at 09:35
  • 3
    The good thing about it is that you can safely check weather the object still exists when the block executes. Otherwise you'll be calling nil, which means your block won't do much. I advice you watch [this video from the WWDC 2012](https://developer.apple.com/videos/wwdc/2012/?id=712) ;). – Gianluca Tranchedone Jun 14 '13 at 09:45
  • 1
    @EnzoTran: you want to create a strong reference because the weak reference is "safe" only because you know `self` will still be a valid object by the time the block executes. But there is no guarantee that it is not deallocated by the time the inner block executes, which is why it should capture a strong reference. – newacct Jun 16 '13 at 01:49
  • I wish Objective-C had some kind of syntax for abstracting this boilerplate pattern. I was thinking something like `__weak __strongcapture __typeof(self) weakSelf = self;` Perhaps all weak references should be automatically made strong when accessed within a block, though for backward compatibility __strongcapture would be better. – NathanAldenSr Nov 15 '13 at 18:59
  • 5
    Here's a blog post that has another good explanation of this pattern: http://dhoerl.wordpress.com/2013/04/23/i-finally-figured-out-weakself-and-strongself/ – smileyborg Dec 09 '13 at 22:53
  • 3
    +1 for "strong pointer within the block will only exist until the block completes" – onmyway133 Jun 23 '14 at 16:33
  • you do not need the condition for strongSelf. If you do not plan to do anything specific in case it is not nil, it is safe to call method on nil - will do nothing – Julian Oct 19 '15 at 09:00
19

It depends.

You only create a retain cycle if you actually store the block (because self points to the block, and block points to self). If you don't intend to store either of the blocks, using the strong reference to self is good enough --- block will be released first after it got executed, and then it will release it's pointer to self.

In your particular example, unless you're performing more operations which are not shown, you don't need to create any weakerWeakerEvenWeakerSelfs.

George Karpenkov
  • 2,094
  • 1
  • 16
  • 36
  • So I understand the part about a weak self is needed if for example self retains the block. But what kind of operations could I perform, that I will need weakerSelf? – Enzo Tran Jun 14 '13 at 09:32
  • 1
    Actually, I think you never need `weakerSelfs` - weak pointer is marked as not increasing the reference count, and hence there is no way to make it "weaker". – George Karpenkov Jun 14 '13 at 09:36