Question

I have been going questions about retain cycle but most of them talk about defining a block explictly and holding a strong reference to it. None of them talks about just passing an inline block. My understanding is that just passing block in a function as an argument, does not create a strong reference. But i just want to make sure I havent misunderstood.

So the question is: Does passing a block in a member function create a strong reference?

    [self someFunctionWithCompletionCallback:^{
        [self completionFunctionality];
    }];

In this case is self holding a strong reference on the block being passed?

That would decide if I need to pass in weakSelf or not.

Thanks

Was it helpful?

Solution

It depends on what that someFunctionWithCompletionCallback: does. If the method stores that block in a strong member variable, for example, it would cause a retain cycle. If the method just calls the block during its execution and does not store it, no permanent retain cycle is created.

Note that something like this:

- (void)someFunctionWithCompletionCallback:(void (^)())completionBlock {
    dispatch_async(^{ completionBlock() }); 
}

Will retain self temporarily (until the async dispatch is completed), since dispatch_async will retain its block, which will retain the completion block, which will retain self.

OTHER TIPS

Remember the definition of a cycle is A->B->A (where '->' means 'retains'). In your question, B is a block and A is an object defining the block literal. B->A is certainly true, because blocks retain objects referred to within them and B refers to A.

But does A->B? That's up to A. Just passing an object doesn't retain it (imagine if that were the case, infinite retains everywhere!). So how does A handle B? If A copies or retains B, then A->B, and you have a cycle. If it doesn't, you don't.

When you call [self completionFunctionality]; in block body it (block) retains self so it creates strong reference. When execution of block is finished, it becomes out of scope, as result it would be removed from stack and block breaks strong reference to self. It means that self couldn't be dealloced until block execution is finished. So it isn't retain cycle in common understanding.

This code doesn't create retain cycle. It would be retain cycle if the block was for example a strong or copy property

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top