UIViewController -dealloc method not called
Asked Answered
Z

4

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.

Zemstvo answered 4/5, 2013 at 9:39 Comment(13)
@ThilinaHewagama -viewDidDisappear: does work, but does this method indicate deallocation ?Zemstvo
I have never had NSZombieEnabled on and I think this issue is resolved in iOS6.Zemstvo
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.Tremain
@Tremain 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.Zemstvo
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.Tremain
@Tremain 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 ?Zemstvo
How are you able to refer to the controller in order to present it in the first place?Kylix
@Kylix I just set it up as the root view controller in Interfacebuilder for the sake of the test.Zemstvo
You have to present something before you can dismiss it. Are you doing that. Post you code!Tremain
@Tremain 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...Zemstvo
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.Tremain
@Tremain 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.Zemstvo
@MartinE.: can you show the code?Kylix
T
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;
}
Tremain answered 4/5, 2013 at 22:1 Comment(1)
Perfect ! Exactly what I needed. Thanks for your patience rdelmar and have a nice day :).Zemstvo
W
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")
}
Waits answered 4/5, 2013 at 9:50 Comment(1)
sorry I should have included in my question that I am already calling -dealloc. The problem is, it does not get called at all...Zemstvo
B
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.

Bagger answered 4/5, 2013 at 10:5 Comment(3)
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.Zemstvo
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.Bagger
Ok, thanks mariusLAN. I am not particularly familiar with Instruments, which instrument should I use to see retains/releases ?Zemstvo
B
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.

Beard answered 4/5, 2013 at 13:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.