Michael
Michael

Reputation: 1238

UIPopoverController and content ViewController - memory management question

Please check my approach concerning release of both UIPopoverController and loadViewController


- (IBAction) manageCardSets:(UIBarButtonItem*)baritem {
    LoadViewController *loadViewController = [[LoadViewController alloc] initWithStyle:UITableViewStylePlain]; 

    self.loadPopover = [[UIPopoverController alloc] initWithContentViewController:loadViewController];
    self.loadPopover.delegate = self;

    [self.loadPopover presentPopoverFromBarButtonItem:baritem permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];   

    [loadViewController release];
}

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {

    [popoverController.contentViewController release];
    self.loadPopover = nil;
    [_loadPopover release]; 
}

As you can see I release loadViewController twice and the code works, no leaks, but I have some doubts. If I release it once, than the dealloc is not called in loadViewController.

Upvotes: 1

Views: 1759

Answers (1)

albertamg
albertamg

Reputation: 28572

If your loadPopover property is retain/copy, the following line is over-retaining the object and leaking:

self.loadPopover = [[UIPopoverController alloc] initWithContentViewController:loadViewController];

Both, alloc-init and the property accessor retain the object. This should be:

self.loadPopover = [[[UIPopoverController alloc] initWithContentViewController:loadViewController] autorelease];

This is why the loadPopover object only gets deallocated if you send it two release messages but you should never resort to these tricks.

EDIT:

You also have another memory management problem. You are releasing an object you do not own in this line:

[popoverController.contentViewController release];

It is the popoverController responsability to retain/release the contentViewController. By doing this you are over-releasing the contentViewController.

To sum up, your code would look like this:

- (IBAction) manageCardSets:(UIBarButtonItem*)baritem {
    LoadViewController *loadViewController = [[LoadViewController alloc] initWithStyle:UITableViewStylePlain]; 

    self.loadPopover = [[[UIPopoverController alloc] initWithContentViewController:loadViewController] autorelease];
    self.loadPopover.delegate = self;

    [self.loadPopover presentPopoverFromBarButtonItem:baritem permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];   

    [loadViewController release];
}

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
    self.loadPopover = nil;
}

Upvotes: 1

Related Questions