4

I noticed Apple's documentation saying we need to avoid strong reference cycles when capturing self.

The block in the example is a property of self.

But what if I put a block as a local variable in a dispatch_async statement?

In this case, it will not create a retain cycle even if I directly call a method of self, right?

Is the following code generating weakSelf required in this article?

// your code
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
    __strong typeof(weakSelf) strongSelf = weakSelf;
    if (strongSelf) {
        [strongSelf doThis];
        [strongSelf doThat];
        [Manager.sharedInstance updateSuccessCount];
    }
});

// more code
7
  • 2
    Update your question with relevant code. Commented Apr 13, 2016 at 18:32
  • You’re right, this will not result in a cycle since the block itself is released when the callback is called. But if the callback were stored in a variable, you should consider when (and if) it is released. In Apple’s example, the block is only released when self.block is re-assigned or self is released. However, self will never be released since there’s always the reference from the block still around. Commented Apr 13, 2016 at 18:36
  • @rmaddy Hi I've updated the code here. Commented Apr 13, 2016 at 19:08
  • @RaphaelSchweikert Thanks, I agree with you. I just updated the question with some sample code. Commented Apr 13, 2016 at 19:10
  • Just a side note, the code above doesn't guarantee that strongSelf will be valid. If weakSelf becomes nil right before the assignment statement then strongSelf will be nil. All that strongSelf guarantees here is that it will be either a valid object or nil for the remainder of the block. If you want to guarantee the object is non-nil, put the strongSelf declaration just before the if statement and check to see if strongSelf is nil instead. Commented Sep 3, 2016 at 21:41

1 Answer 1

6

In the example given, using dispatch_async, there would be no retain cycle, so it would be safe to capture self strongly here. The only difference would be that if self were released by everything else between when this dispatch_async was called and when the block actually ran, it would slightly delay the actual deallocation of self for that brief time, and could affect which thread the deallocation actually occurs on as well. But in general there's no harm in doing it either way when using dispatch_async.

One case where you may want to do it the way your example is written above is if the code run in the block is somewhat expensive and would only want to be done if absolutely necessary, and that it's unnecessary if self had already been released by everything else.

Another case may be if self uses a large amount of memory and gets deallocated normally right before something else starts consuming a lot of memory. In that case you may not want those two instances to be allocated at the same time.

Sign up to request clarification or add additional context in comments.

1 Comment

Good to know. I agree with you. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.