UIPopoverController's contentViewController.viewDidUnload not getting called

935 views Asked by At

When I use a UIPopoverController and give it a contentViewController, I cannot seem to get the contentViewController to correctly be deallocated (as evidenced by the fact that the contentViewController.viewDidUnload is never getting called).

Code to create and display the popup:

PopupTestViewController *popupTest = [[PopupTestViewController alloc] initWithNibName:@"PopupTestViewController" bundle:nil];
popupTest.mainViewController = self;
self.popoverController = [[UIPopoverController alloc] initWithContentViewController:popupTest];
self.popoverController.popoverContentSize = popupTest.view.frame.size;
self.popoverController.delegate = self;
[self.popoverController presentPopoverFromRect:button.frame inView:button.superview permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

Now I am assuming that the contentViewController (in the code above, this is PopoverTestViewController) should be deallocated when the UIPopoverController is closed (whether by clicking off of it, or be explicitly dismissing it). But viewDidUnload is never called. I did notice, however, that if I define a dealloc method for PopoverTestViewController, that is called appropriately.

So my question is: why is viewDidUnload never getting called? (And I'm using ARC).

2

There are 2 answers

0
Jiri On BEST ANSWER

viewDidUnload is not guaranteed to get called. It only gets called when the application receives a memory warning and the receiving ViewController has view loaded but is off screen. When the view is loaded and retain count reaches zero, viewDidUnload is not called.

You can find more details in the documentation. Instructions on when to release what objects can be found in the same document.

1
Shaggy Frog On

This is a little different than I've used UIPopoverController. Since you manually alloc'ed popupTest, you definitely need to manually release it. The UIPopoverController instance will retain popupTest when initWithContentViewController: is called.

Furthermore, if you are defining the popoverController property with retain, then you're getting a double-retain when you use the self.popoverController setter by assigning directly from the alloc. The general pattern for setting a @property is:

@property (nonatomic, retain) Foo* foo;

...

Foo* aFoo = [[Foo alloc] init];
self.foo = aFoo;
[aFoo release];