2009-10-31 9 views
0

Je programme ma première application iPhone (qui se bloque avec une erreur EXC BAD ACCESS).Aide pour les débutants: quand appeler [release obj]?

J'ai lu quelques autres réponses similaires, mais je n'ai toujours pas une image claire de la façon de réparer mon code.

Quelqu'un peut-il aider à résoudre ma gestion de la mémoire pour l'objet cellulaire UITableViewCell * dans cet extrait:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:kCityCellReuseID]; 
    if (cell == nil) 
    { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCityCellReuseID]; 
     cell.selectionStyle = UITableViewCellSelectionStyleBlue; 
     cell.textLabel.text = [[self.myData objectAtIndex:indexPath.section] valueForKey:kDisplayText]; 
     [cell release]; 
    } 
    return cell; 
} 

Répondre

4

Vous devez appeler [cell autorelease] au lieu de [cell release]. Lorsque vous relâchez la cellule, elle est désaffectée immédiatement avant que vous puissiez la renvoyer à la vue de la table et la vue de table peut en prendre possession (c'est-à-dire la conserver). Si vous autorelease la cellule, vous signalez que vous abandonnez la propriété de l'objet (ce qui est la bonne chose à faire depuis que vous l'avez créé avec alloc), mais il ne sera pas libéré tant que le pool de libération automatique ne sera pas disponible. il. À ce moment-là, la vue de la table aura conservé la cellule.

Si vous n'avez pas libéré automatiquement la cellule (c'est-à-dire si vous avez supprimé la ligne de relâchement), votre programme ne tomberait pas en panne, mais il perdrait de la mémoire chaque fois qu'une nouvelle cellule serait créée.

+0

La libération ne supprime jamais rien immédiatement. Il décrémente simplement son nombre de retenue. –

+3

@NSD: Et si l'objet a un nombre de retenue de 1, l'objet sera immédiatement désalloué. – Chuck

+1

Non ce ne sera pas. Il peut être désalloué lors du prochain voyage dans la boucle d'exécution, mais jamais immédiatement. Tout cela a été documenté de manière très approfondie pendant des décennies maintenant. –

0

Votre application se bloque parce que vous renvoyez un objet déjà publié dans votre fonction. Vous pourriez au lieu de le relâcher dans votre fonction passer la propriété à l'appelant de la fonction. Ensuite, c'est à l'appelant de libérer l'objet quand il en a fini avec lui.

+0

Vous avez raison de dire que la version est à l'origine du crash, mais le simple fait de renvoyer l'objet à l'appelant est totalement contraire aux règles de gestion de la mémoire Cocoa. – Chuck

+0

Vous avez raison, bien que cela fonctionne, il doit être pris avec précaution. – Mez

Questions connexes