3

I'm trying to get my head around how object lifetime and reference counting interact with code blocks. In the following code I'm just doing a simple animation that flashes as the top view on a UINavigationController's stack is swapped. The tricky part is that the popped view controller is the one where this code is defined.

[UIView animateWithDuration:0.2 
        animations:^{self.navigationController.view.alpha = 0.0;}
        completion:^(BOOL finished){ 
                UINavigationController *navController = self.navigationController;  

                [self.navigationController popViewControllerAnimated:NO]; 
                [navController pushViewController:nextView animated:NO];
                [nextView release];

                [UIView animateWithDuration:0.2 
                        animations:^{navController.view.alpha = 1.0;}];                    
                 }];    

My question is (ignoring what the animation looks like), is this the correct way to do this from a memory management perspective. In particular:

(1) When using this approach for the pop+push cycle, is it correct that it is no longer necessary to retain self, as in other similar examples that do not use blocks?

(2) Does invoking animateWithDuration:... with the these blocks retain the defining view controller (self) until the blocks execute?

1 Answer 1

5

(1) When using this approach the the pop+push cycle, is it correct that it is no longer necessary to retain self, as in other similar examples that do not use blocks?

It is correct. These blocks automatically retain self, navController and nextView if nextView is local variable.

(2) Does invoking animateWithDuration:... with the these blocks retain the defining view controller (self) until the blocks execute?

These blocks are copied to heap from stack by this method. And these blocks are released after execution. And then self, navController and nextView are released from these blocks.

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

4 Comments

So 'self' and the navController are retained because they are actively referenced from inside the block correct? If however, the above code did not have the line "navController = self.navigationController", but instead had "navController = mNavigationController" - where mNavigationController is an ivar, then mNavigationController would have been retained, but not 'self'. Right? I just want to confirm whether or not blocks automagically retain their 'host' instances, namely 'self'.
"self.navigationController" is same as "[self navigationController]", and "mNavigationController" is same as "self->mNavigationController", thus self is retained in both cases. If you want to avoid retaining self, use local variable as "UINavigationController *controller = self.navigationController;", and then use "controller" in blocks.
I did ATSDragToReorderTableViewController *blockSelf = self; and used the local blockSelf, but somehow self is still retained and not released (dealloc of self not being called when I pop it). What did I do wrong???
hmm, I recommend you to create a question with your code snippet.

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.