2011-02-22 3 views
0

Juste une petite question vraiment:Gestion de la mémoire dans tableviewDataSource

J'exécute une méthode pour tirer des enregistrements à partir d'une base de données SQLite dans un tableau, attribuant alors le contenu de ce tableau à une variable d'instance.

@interface { 
NSArray *items; 
} 

@implementation 
// The population method. 
-(void)populateInstanceVariable 
{ 
    NSMutableArray *itemsFromDatabase = [[NSMutableArray alloc] init];   

    // Sqlite code here, instantiating a model class, assigning values to the instance variables, and adding this to the itemsFromDatabase Array. 


    self.items = itemsFromDatabase; 
    [itemsFromDatabase release]; 

} 
// viewDidLoad is calling the method above 
-(void)viewDidLoad 
{ 
    [self populateInstanceVariable]; 
    [super viewDidLoad]; 
} 

// TableViewDataSource method - cellforIndexPath 
- (UITableViewCell *)tableView:(UITableView *)passedInTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault]; 

    // Load in my model from the instance variable - ***1 
    MyDataModel *model = [items objectAtIndexPath:indexPath.row]; 

    // Assign the title to the cell from the model data 
    cell.textLabel.text = model.title; 

    // This is the part i'm stuck on, releasing here causes a crash! 
    [model release]; 

    return cell; 

} 

@end 

Ma question est double:

  1. Est-ce que je fais pour affecter des données à l'instance droit variable? et suis-je gérer correctement la mémoire?
  2. Comment gérer la mémoire de cet élément de modèle dans la source de données tableview? La seule façon que je puisse faire fonctionner correctement est que je ne libère pas du tout l'objet *model, mais cela cause sûrement des fuites?

Cheers.

Répondre

2

Non, vous n'êtes pas la gestion de la mémoire correctement ici:

  • vous devez utiliser « réutilisables » UITableViewCells, la plupart des exemples de uitableview montrent comment faire, et

  • ne font pas [modèle release], vous ne « propre » l'objet dans ce cas, vous êtes juste référence à ce que vous ne devez pas libérer

Voici le cellForRowAtIndexPath typique:

-(UITableViewCell *) tableView:(UITableView *)atableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *CellIdentifier = @"CellIdentifier"; 

    // Dequeue or create a cell of the appropriate type. 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) 
    { 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease]; 
     // settings that do not change with every row 
     cell.selectionStyle = UITableViewCellSelectionStyleGray; 
    } 
    // settings that change with every row 
    cell.textLabel.text = @"fill in your label here"; 
    return cell; 
} 

De plus, si vous utilisez un DB pour vos données, vous pouvez regarder dans les données fondamentales, les données d'Apple cadre persistance/gestion, il inclut la possibilité de raccorder les aspects de vos entités de données directement en à UITableViews.

+0

Merci, je suis en train d'utiliser les tablesviewcells réutilisables, je ne pouvais pas être dérangé de les écrire dans la question. –

+0

Des idées sur l'affectation initiale à la variable d'instance? c'est-à-dire où est le meilleur endroit pour le faire, dans viewWillAppear, viewDidLoad? etc. –

+0

Ajout au second point. Posséder signifie: vous avez fait un 'retain', 'alloc/init', 'new' ou 'copy'. –

0

1) La méthode de peuplement est correcte. N'oubliez pas de mettre la variable d'instance à zéro dans le dealloc. (Je suppose que vous avez ajouté une propriété/synthétiser comme vous avez utilisé le 'soi').

2) NE PAS libérer l'objet du modèle. Vous ne l'avez pas conservé, copié ou attribué dans cette méthode. Par contre votre initialisation de la cellule est fausse. Utilisez ce qui suit: (Mieux pour la performance)

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *Identifier = @"CellIdentifier"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier]; 
    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:Identifier] autorelease]; 
    } 

    //Other code 
} 
+0

Oui, j'utilise des tablecells réutilisables, je les ai juste omis de la question pour la vitesse. –

+0

Merci pour l'aide! :) –

+0

Aucun problème, s'il vous plaît obtenir la gestion de la mémoire claire pour vous-même (la libération de l'objet modèle échoue), c'est un problème important si vous ne vous familiariser avec elle, vous allez dans les pièges plus tard. Bonne chance. –