Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIPopoverController and memory management

    UIPopoverController *historyPop = [[UIPopoverController alloc] initWithContentViewController:nav];
    [nav release];
    [historyPop setPopoverContentSize:CGSizeMake(400, 500)];
    [historyPop presentPopoverFromRect:CGRectMake(button.frame.origin.x, button.frame.origin.y, button.frame.size.width, 5) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
    //[historyPop release];

This is my current code, however the Analyser says that the is probably a leak, which there is (as the release line is commented out). But if I uncomment the release line then the app crashes and says dealloc was reach on the popover while it is still visible, so when exactly should I be releasing the popover controller?

like image 406
Jonathan. Avatar asked Dec 07 '10 19:12

Jonathan.


2 Answers

As mentioned in several places, the methods that present a popover (either from a rect, or from a toolbar button) do not retain the popover. So, your presenting view controller needs to hold a reference to it and release it at the appropriate time.

You can do this by setting the presenting view controller as the popover's delegate, as mentioned. A simpler, if slightly less memory-efficient, approach is to declare a retain property to hold the UIPopoverController. When you create the popover you assign it to the property, which retains it. If you later create another popover, it will release the previous popover when you reassign the property. Don't forget to release the property in the presenting view controller's dealloc method (as well as viewDidUnload).

This approach won't leak, and you don't need to deal with delegates. But, you will potentially keep a UIPopoverController object around longer than necessary. It's up to you to determine if that's a concern for your app.

like image 95
Adam Milligan Avatar answered Nov 04 '22 16:11

Adam Milligan


Try autoreleasing the popover: [historyPop autorelease]. presentPopoverFromRect does not retain the popover, so autorelease won't work here. You need to setup your class as a delegate of the popover controller, and release the popover in popoverControllerDidDismissPopover:.

like image 41
bosmacs Avatar answered Nov 04 '22 16:11

bosmacs