0

If a block is only using self to call a method, is it necessary to weakify it to prevent retain cycle?

This is not a duplicate of another post, I am not asking if this needs to be done within UIView animation block, but whether it needs to be done when self block is only calling method call. I have added a dispatch_async example as well.

@weakify(self);

// Need to strongify?
dispatch_async(dispatch_get_main_queue(), ^{
    @strongify(self);
    [self doSomething];
});

// Need to strongify?
[UIView animateWithDuration:0.125 animations:^{
    @strongify(self);
    [self layoutIfNeeded];
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
Boon
  • 40,656
  • 60
  • 209
  • 315
  • You don't need weak references in `UIView` animation blocks. There is no strong reference cycle here. – Rob Mar 22 '17 at 20:54
  • @Rob Does the use of self to call a method create a reference to self? – Boon Mar 22 '17 at 20:55
  • No @Boon, it's because for there to be a cycle, self needs to retain the block -- either directly or indirectly. The block retains self, but self does not retain the block. – danh Mar 22 '17 at 20:56
  • Yes, you need the reference to self to call the method. Think of the call as taking an extra argument (the self). – Lou Franco Mar 22 '17 at 20:57
  • Just to clarify (danh is right) There is no cycle, but there is a reference to self in the block – Lou Franco Mar 22 '17 at 20:58
  • Thanks - can one of you answer the question with the proper info and I will select. – Boon Mar 22 '17 at 20:59
  • @Rob So would you say only when the block is initiated by self (or property of self) does it need to use weakify/strongify? – Boon Mar 22 '17 at 21:06
  • 2
    No. You need to use weak reference to self if the block is going to (potentially) outlive `self` (or, more critically, if you have a strong reference cycle). `UIView` block-based animations are a bit of a special case. There certainly is no strong reference cycle here and the animation engine is quite clever about handling the blocks for dismissed views. Even if you have a completion handler in your animation, it's getting resolved when the scene is dismissed. Now, if you were doing asynchronous network requests or the like, you'd have to be more diligent. But not with `UIView` animations. – Rob Mar 22 '17 at 21:21
  • @Rob Thank you - very good info. So with dispatch_async, you would need to then? Can you leave your answer below - I will pick as the right answer. – Boon Mar 22 '17 at 21:22
  • So, yes, if you use `dispatch_async` it could be a problem (though it would be resolved as soon as the `dispatch_async` fires, so its often of neglible concern). Where it's really problematic is with repeating timers or anything asynchronous that might take a lot of time. Or strong reference cycles. Then it's definitely a problem. Just not `UIView` block-based animations. Thanks for the offer, but given this has been marked as duplicate, no, I can't leave an answer. – Rob Mar 22 '17 at 21:24
  • @Rob This is not a duplicate - it was marked erroneously because the example happened to use animation block. I have added dispatch_async as another example. – Boon Mar 22 '17 at 21:42

1 Answers1

2

In this case you don't need to weakify, because the block is not retained by self. So there is no retain cycle.

Do we need to use __weak self inside UIAnimationBlocks in ARC?

Community
  • 1
  • 1
Ehren Murdick
  • 426
  • 3
  • 8