5

I am working with Automatic Reference Counting. I have a custom UIViewController subclass and whenever I call -presentViewController: animated:completion: or remove its view from the superview I would like to NSLog something like "I am dealloced" so I know that the view controller has successfully been removed. I have implemented the -dealloc method in my view controller. However I started a test project where I just had two UIViewController instances (no retain cycles) and -dealloc is not called either when I push the second UIViewController modally or when I remove the superview or when I remove it from the parent view controller. Am I missing something ? In my original project (not the test case) Instruments shows me that those controllers leave a memory footprint that I can't get rid off.

the_critic
  • 12,720
  • 19
  • 67
  • 115
  • @ThilinaHewagama `-viewDidDisappear:` does work, but does this method indicate deallocation ? – the_critic May 04 '13 at 09:47
  • I have never had NSZombieEnabled on and I think this issue is resolved in iOS6. – the_critic May 04 '13 at 09:57
  • 1
    It's not at all clear from what you posted at Github what you're trying to do. Removing a controller's view from the window doesn't deallocate the controller. You should post here, an example of what you're doing -- show the whole code for the controller you think should be deallocated. It helps to see it in context. – rdelmar May 04 '13 at 16:09
  • @rdelmar I thought removing the controller's view would deallocate the controller as well... But yeah I am trying to actually get rid of the whole controller not just the view, so that the view controller gets dealloced. – the_critic May 04 '13 at 17:32
  • How you do that depends a lot on your structure. Dismissing a presented controller, or popping a controller off a navigation stack both should cause deallocation. Also, if you just switch the root view controller of the window, and yours is the one you're switching away from, that will also cause it to be deallocated. – rdelmar May 04 '13 at 18:24
  • @rdelmar yeah but nothing really seems to work. I set up a test environment with 2 view controllers. first one has a button, when I tap it, the controller gets dismissed via `-dismissViewControllerAnimated:completion:`. shouldn't that call the `-dealloc` method ? – the_critic May 04 '13 at 18:36
  • How are you able to refer to the controller in order to present it in the first place? – newacct May 04 '13 at 19:03
  • @newacct I just set it up as the root view controller in Interfacebuilder for the sake of the test. – the_critic May 04 '13 at 19:28
  • You have to present something before you can dismiss it. Are you doing that. Post you code! – rdelmar May 04 '13 at 19:36
  • @rdelmar yeah but look at mariusLAN's answer below, he says when I present a VC it retains the parent view controller so it keeps a reference to it and thus does not get dealloced... – the_critic May 04 '13 at 19:40
  • Yes that's true. So what? You haven't made it clear what you want. When you present a controller, it's with the idea that you will later dismiss it, and you want to go back to the one that presented it, therefore, you don't want that presenting one to be deallocated. If that's not what you're trying to do, then you need to say what it is you are trying to do. – rdelmar May 04 '13 at 21:08
  • @rdelmar I am sorry that I can't/couldn't get across my point. I don't want any reference to the old controller. What I want to do, is remove VC1 completely -- NO REFERENCE whatsoever -- and have VC2 as the current view controller. VC1 should not exist anymore, its references should be gone. – the_critic May 04 '13 at 21:46
  • @MartinE.: can you show the code? – newacct May 04 '13 at 22:25

4 Answers4

11

If you want to switch view controllers, and have the one you're switching away from be deallocated, then just switch the root view controller of the window. So, if you're in VC1 and want to go to VC2, then do this in VC1:

VC2 *vc2 = [[VC2 alloc] init]; // or however else is appropriate to get an instance of this class
self.view.window.rootViewController = vc2;

If you haven't created any property to point to vc1, then it will be deallocated after making this switch.

If you want to use a modal presentation or a modal segue (to get the animation when you switch controllers), you can still get the initial controller to be deallocated by switching the root view controller after the presentation from the viewDidAppear method of vc2:

-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    self.view.window.rootViewController = self;
}
rdelmar
  • 103,982
  • 12
  • 207
  • 218
0

To get a print when the View Controller is deallocated you can implement the dealloc method as

- (void) dealloc {
    NSLog(@"The instance of MyViewController was deallocated");
}

Then to get a print when the View Controller left the view you can implement

- (void) viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    NSLog(@"The instance of MyViewController left the main view")
}
Groot
  • 13,943
  • 6
  • 61
  • 72
  • sorry I should have included in my question that I am already calling `-dealloc`. The problem is, it does not get called at all... – the_critic May 04 '13 at 09:52
0

If you use -presentViewController:animated:completion: you are retaining the parentViewController every time you call this method. ModalViewControllers are simply pushed on top of the other ViewController.

ModalViewControllers are only designed for some kind of information / User Input and stuff like that. If you want to dealloc the ParentViewController you have to deal with your own implementation.

mariusLAN
  • 1,195
  • 1
  • 12
  • 26
  • Thanks for your answer, it was useful. But the problem is, I do not really call the `-presentViewController:animated:completion:` method. I just tried to exemplify my case. In reality I just add the view of my custom VC to another superview that is not connected to the old VC. – the_critic May 04 '13 at 10:09
  • Try to look at instruments. The problem here is that you only remove the view from the superview and the ViewController is retained by some other Object. The best way to solve this problem is to look in instruments and lookup the retain and releases that are called on the object. – mariusLAN May 04 '13 at 10:36
  • Ok, thanks mariusLAN. I am not particularly familiar with Instruments, which instrument should I use to see retains/releases ? – the_critic May 04 '13 at 10:39
0

dealloc method isn't called when the class is retained (or something in this class is retained) and not reeleased. It is justly for projects with both ARC and without it. So check your code twice.

user2159978
  • 2,629
  • 2
  • 16
  • 14