views:

103

answers:

0

Hi,

I'm using a UISplitViewController where when the Master VC is loaded (UITableViewController) and a table cell is pressed, it creates the Detail VC (UIViewController with two UIWebViews):


@implementation MasterVC

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    UIViewController  *detailViewController = nil;
    DetailVC *newDetailViewController = [[DetailVC alloc] initWithNibName:@"DetailVC" bundle:nil];
    detailViewController = newDetailViewController;

    // Update the split view controller's view controllers array.
    NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailViewController, nil];
    splitViewController.viewControllers = viewControllers;
    [viewControllers release];

    [detailViewController release];
}

If I simulate a memory warning, the DetailVC is released (didReceiveMemoryWarning, viewDidUnload, dealloc are called) but I get a "-[UIView _invalidateSubviewCache]: message sent to deallocated instance" error at the line in MasterVC where I release the viewControllers, which make sense since since it tries to load the detailViewController (DetailVC) which was released due to the memory warning. Why it has to release the detail vc since it's view is the one being displayed, I don't fully understand.

Now, if instead of releasing the detailViewController inside didSelectRowAtIndexPath, I release it inside viewWillDisappear, everything works fine:


@implementation MasterVC

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    UIViewController  *detailViewController = nil;
    DetailVC *newDetailViewController = [[DetailVC alloc] initWithNibName:@"DetailVC" bundle:nil];
    detailViewController = newDetailViewController;

    // Update the split view controller's view controllers array.
    NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailViewController, nil];
    splitViewController.viewControllers = viewControllers;
    [viewControllers release];

    // Released in viewWillDissapear   
    //[detailViewController release];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    MyAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
    // Retrieve the detail vc and release it-[UIView _invalidateSubviewCache]: message sent to deallocated instance
    [[delegate.splitViewController.viewControllers objectAtIndex:1] release];
}

For me, it makes (some) sense to release the detail view controller when the master view controller will dissapear, but still, it kind of seems like a hack (plus the Static Analyzer complains of not releasing the detail vc in the 'right' place). Any other better ways to solve this?