Jordan Smith
Jordan Smith

Reputation: 10378

Bad memory leak when creating a view - even though a 'release' is present?

Part of my code presents a UITableViewController in the following way:

FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:@"Settings" bundle:nil];
flipside = [[UINavigationController alloc] initWithRootViewController:controller];  
controller.delegate = self;
flipside.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:flipside animated:YES];
[flipside release];
[controller release];

Using the leaks tools, no memory leaks are picked up on. However, whenever I bring up the settings menu (as shown in the code above), more memory appears to be allocated and never released - almost 100 kB every time.

Weirdly, the inclusion of the two release statements at the end seems to have no effect on the memory allocation..? Is there something I am misunderstanding about memory allocation in objective-c, or is something weird going on?

Any ideas are much appreciated - thanks!

Upvotes: 0

Views: 197

Answers (1)

Rich
Rich

Reputation: 1090

If flipside is a retained property then the navigation controller is leaking. the problem is that you are bypassing the accessor method and releasing flipside directly. This is just messy code. A better way to do it would be to make an accessor method for flipside that will only alloc a new one if you haven't already created one. It's called lazy loading. To do this, just leave the @synthesize for flipside (but you shouldn't set it from outside the accessor method), in your header file change the property to, and add this method to the implementation:

- (UINavigationController *)flipside {
    if (flipside != nil) {
        return flipside;
    }
    FlipsideViewController *controller = [[[[FlipsideViewController alloc] initWithNibName:@"Settings" bundle:nil];
    controller.delegate = self;
    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller];
    [controller release];
    navController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
    // This implies a retain if your flipside property is set to retain
    self.flipside = navController;
    [navController release];
}

make sure to put self.flipside = nil in the viewDidUnload method of the view controller the code you included came from (I assume it's a presentSettings action). what your presentSetting action should now look like is this:

- (IBAction)presentSettings {
    // make sure you use the accessor self.flipside instead on accessing the variable directly
    [self presentModalViewController:self.flipside animated:YES];
}

Upvotes: 1

Related Questions