Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

__block self reference cycle in ivar block in ARC

I've got some code with an apparent reference cycle in a block ivar. The following code causes a reference cycle and dealloc is never called:

__block MyViewController *blockSelf = self;

loggedInCallback = ^(BOOL success, NSError *error){
    if (success)
    {
        double delayInSeconds = 1.0;
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void)
        {
            [blockSelf.delegate loginDidFinish];
        });            
    }
};

However, if I create another __block variable to hold a reference to my delegate for the block's scope to capture, the reference cycle goes away:

__block id <MyViewControllerDelegate> blockDelegate = self.delegate;

loggedInCallback = ^(BOOL success, NSError *error){
    if (success)
    {
        double delayInSeconds = 1.0;
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void)
        {
            [blockDelegate loginDidFinish];
        });            
    }
};

Just want to understand what's going on here.

like image 782
Ash Furrow Avatar asked Jan 18 '12 19:01

Ash Furrow


1 Answers

I'm going to assume your'e using ARC here. Prior to ARC, your first example would work just fine. With ARC the semantics of __block have changed. __block declarations are now strongly captured, rather than weakly. Replace __block with __weak in your first sample and all should work as expected.

As for what the second example works, you are creating a strong reference to the delegate, but your that doesn't have a reference back to your object. Thus no cycle and everyone is happy.

I recommend reading Mike Ash's article on the changes introduced with ARC, especially around block capture and __weak http://www.mikeash.com/pyblog/friday-qa-2011-09-30-automatic-reference-counting.html

like image 67
Joshua Weinberg Avatar answered Oct 14 '22 07:10

Joshua Weinberg