Take the 2-minute tour ×

I'm still struggling a bit with the idea of ARC. Let's suppose I have two very complex viewControllers A and B that each have a lot of pictures in them which are retained by each view. For argument's sake, let's suppose the first ViewController (A) retains images which take up 75 MB in RAM. The other one (B) takes up 75 MB as well.

In my App Delegate I set up my NavigationController like so:

ViewControllerA *vcA = [[ViewControllerA alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:vcA];
[navController.navigationBar setHidden:YES];
[[self window] setRootViewController:navController];

When I switch from A to B, I do it like so in ViewControllerA.m:

ViewControllerB *vcB = [[ViewControllerB alloc] init];
[[self navigationController] pushViewController:vcB animated:YES];

When I switch back, I do it like so in ViewControllerB.m:

[[self navigationController] popToRootViewControllerAnimated:YES];

Now my big question is if I still have ViewController A in my memory when I'm in ViewController B? In this case, when does the compiler release a ViewController? Could I or should I release (i.e. set it to nil) one ViewController when it is not in use?

I'm sorry if the answer is clear or if I'm totally missing the point. So any answers and explanations would be highly appreciated.

share|improve this question

3 Answers 3

up vote 1 down vote accepted

Your view controller A will be retained by navController so it won't be released. Even you set vcA to nil it will not be released because navController is retaining it. The problem is that your controller retained lots resources (images) that takes lots memory. To solve this, you can allocate the resources on viewDidLoad and free them at viewDidUnload

for example

// in your view controller
- (void)viewDidLoad {
    [super viewDidLoad];
    self.image = // read image to memory

- (void)viewDidUnload {
    [super viewDidUnload];
    self.image = nil; // release the image to free memory

Then after view controller B is pushed to navController, view controller A will get notified by UIKit that it is not the displaying controller and it will unload the view if necessary in order to free memory for other class to use.

share|improve this answer
Excuse me, but i think you're mistaken. ViewDidLoad and ViewDidUnload are called when the view is created and before the view is destroyed (before dealloc). Maybe you wanted to talk about viewWillAppear and viewWillDisappear methods, witch are called eatch time the viewController's view is shown/hidden. Finally, and that's my own opinion, I think it would be better if images were loaded once, specially if the controller's is ofen shown. –  Martin Mar 13 '12 at 11:13
If you allocate and free image every time view at appear/disappear then every view change will be an expansive operation which may result a laggy application. UIKit know when to unload the view to save unnecessary load/unload work. –  Bryan Chen Mar 13 '12 at 20:54
I'm totally agree with you. What I would to say is there was no difference between alloc/release the images in viewDidLoad/viewDidUnload than in, for example, initWithNibName/Dealloc methods. –  Martin Mar 14 '12 at 8:58
view controller may loan/unload its view for multiple times but only init/dealloc once only and it is different between load view and other resources only when need compare to load everything in init –  Bryan Chen Mar 14 '12 at 10:22

Yes, you still have ViewControllerA (you can see this with Instruments next time). That has nothing to do with ARC, it's the same without it. Let me explain:

You create a UINavigationController and put UIViewController A as the root, A is retained (in ARC it's a strong property or something like that), as you can see UINavigationController needs it right? Now you push UIViewController B, B and A exist on memory, you UINavigationController still needs UIViewController A, it's just not showing and the view can be unloaded, if the system needs memory, but it won't release A. When you pop UIViewController B, it is released, and if there aren't references for it (again, I assume this is how ARC works) it is dealloced.

Now your question is, when is the rootViewController dealloced? Well, UINavigationController always has a root! So, while you have a UINavigationController you have a rootViewController.

Let me know in the comments if you need further explaining.

share|improve this answer

I can't help you with ARC, cause I never used it (and I don't know if I really want).

But I can tell you one thing :

When you push your ViewControllers, they all are in the navigation stack. And untill they are in the stack, they remain in memory.

Without using ARC, if I autorelease eatch viewController I push, it will be released exactly when I would pop it from the stack.

If someone know more about ARC (and when it release allocated object) I would be glad to have more info.


share|improve this answer

Your Answer


