2009-05-25 7 views
1

Lors de l'essai d'une application iPhone expérimentale basée sur UINavigationController, j'ai rencontré un problème lorsque l'utilisateur revenait à la vue précédente.Utilisation de UINavigationController avec des instances UIViewControllers de la même classe et aucune NIB

L'application simple utilise un UINavigationController, sur lequel les nouvelles instances de UIViewControllers sont poussées. Ces instances sont toutes de la même classe (dans cet exemple, classe MyViewController une sous-classe de UIViewController), et sont créées manuellement (n'utilisant pas de NIB). Chaque instance contient une instance UITableView distincte en tant que vue de UIViewController.

La méthode tableView: didSelectRowAtIndexPath suivante est issue de la classe MyViewController. Il crée et pousse un autre exemple MyViewController sur le NavigationController lorsque l'utilisateur sélectionne une cellule de tableau:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    MyViewController *nextViewController = [[MyViewController alloc] initWithNibName:nil bundle:nil]; 
    [self.navigationController pushViewController:nextViewController animated:YES]; 
    [nextViewController release]; 
} 

l'utilisateur peut naviguer vers l'avant à travers une séquence de vues, chacune contenant une table. Le problème se produit lors de la navigation vers l'écran précédent. L'application abandonne et xcode démarre le débogueur.

L'erreur peut être évitée en ne libérant pas l'instance MyViewController dans la méthode tableView: didSelectRowAtIndexPath: ci-dessus, ou en n'appelant pas dealloc sur l'instance 'myTableView' dans la méthode dealloc de MyViewController. Cependant, ce n'est pas une vraie solution. Autant que je sache, le UINavigationController "possède" l'instance UIViewController poussée, qui peut alors être libérée sans risque du client qui l'a alloué. Alors, quel peut être le problème avec cette application expérimentale? Pourquoi cela se terminerait-il lorsque l'utilisateur retournera?

Voici quelques autres méthodes de la classe MyViewController:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { 
     self.title = @"My Table"; 
     myTableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
     myTableView.delegate = self; 
     myTableView.dataSource = self; 
     self.view = myTableView; 
    } 
    return self; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyTable"]; 
    if (cell == nil) 
    { 
     cell = [[UITableViewCell alloc] initWithFrame:CGRectMake(0,0, 300, 50) reuseIdentifier:@"MyTable"]; 
     [cell autorelease]; 
    } 
    cell.text = [NSString stringWithFormat:@"Sample: %d", indexPath.row]; 
    return cell; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    return 3; // always show three sample cells in table 
} 

- (void)dealloc { 
    [myTableView dealloc]; 
    [super dealloc]; 
} 

EDIT:

Correction d'un problème - merci Rob Napier pour remarquer le problème.

La méthode -loadView définit maintenant l'affichage à l'aide d'une instance de UITableView locale:

- (void)loadView { 
    UITableView *myTableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    myTableView.delegate = self; 
    myTableView.dataSource = self; 
    self.view = myTableView; 
    [myTableView release]; 
} 

Répondre

2

vous configurez la vue dans la mauvaise méthode. Vous devez configurer ceci dans -loadView, pas -initwithNibName:bundle:. Voir Afficher le Guide de programmation du contrôleur "Utilisation de View Controllers" pour un exemple.

Questions connexes