2012-02-25 4 views
0

J'essaie de faire une recherche de base de table de sqlite et je continue à trébucher sur une fuite de mémoire que je ne peux pas comprendre, d'autant plus qu'elle n'apparaît qu'avec deux lignes équivalentes.Impossible de trouver la fuite de mémoire iPhone/Objective-C dans la récupération de données sqlite

Ce que je fais est simple:

-Créer un objet (catégorie) de tenir ma ligne de SQLite DB
-Avoir une méthode qui interroge SQLite et retourne un tableau de ces objetcs

Je mets tout le code ici (dépouillé un peu pour simplifier mais j'ai la fuite de mémoire avec ce même code).

category.h:

@interface Category : NSObject { 
    int   catId; 
    NSString *description; 
    int   order; 
    NSString *iconName; 
} 

@property(nonatomic, readwrite, assign) int catId; 
@property(nonatomic, retain) NSString *description; 
@property(nonatomic, readwrite, assign) int order; 
@property(nonatomic, retain) NSString *iconName; 


@end 

category.m:

#import "Category.h" 


@implementation Category 

@synthesize catId; 
@synthesize description; 
@synthesize order; 
@synthesize iconName; 

@end 

Procédé pour récupérer tableau:

-(NSMutableArray *)getAll { 

    NSString *query = "select id, description, catorder, image from category order by catorder"; 
    sqlite3_stmt *statement; 
    NSMutableArray *categoryArray = [[NSMutableArray alloc] init]; 

    if (sqlite3_prepare_v2([[Database sharedDatabase] instance], [query UTF8String], -1, &statement, nil) == SQLITE_OK) { 
     while (sqlite3_step(statement) == SQLITE_ROW) { 
      int  dbId =    sqlite3_column_int(statement, 0); 
      char *dbDescription = (char *)sqlite3_column_text(statement, 1); 
      int  dbOrder =   sqlite3_column_int(statement, 2); 
      char *dbIcon =   (char *)sqlite3_column_text(statement, 3); 

      NSString *desc = [[NSString alloc] initWithUTF8String:dbDescription]; 
      NSString *icon = [[NSString alloc] initWithUTF8String:dbIcon];   

      Category *category = [[Category alloc] init]; 

      category.catId=dbId; 
      category.description = desc; 
      //category.description = @"Test"; 
      category.order = dbOrder; 
      category.iconName = icon; 
      //category.icon = @"test.png"; 

      [desc release];   
      [icon release]; 

      [categoryArray addObject:category]; 

      [category release]; 
     } 
     sqlite3_finalize(statement); 
    } 
    [categoryArray autorelease]; 
    return categoryArray; 
} 

Cette ligne fuites

NSString *icon = [[NSString alloc] initWithUTF8String:dbIcon];   

Cette ligne ne

NSString *desc = [[NSString alloc] initWithUTF8String:dbDescription]; 

Voici ce que les instruments montre: enter image description here

et quand je drill vers le bas: enter image description here

+0

Que vous dit l'analyseur statique? –

+0

Essayez ce qui suit sans le libérer: NSString * icon = [NSString stringWithUTF8String: dbIcon]; – Franck

+0

Que dit-il lorsque vous recherchez des fuites dans Instruments? –

Répondre

2

Vous ne disposez pas d'une méthode dealloc. Vous devez avoir dans votre fichier Category.m:

-(void)dealloc 
{ 
    [description release]; 
    [iconName release]; 
    [super dealloc]; 
} 

De plus, je suis sûr que vous ne pouvez pas avoir une propriété nommée « description ». C'est un nom de méthode réservé.

+0

Yep; - La description (NSString *) est implémentée dans NSObject. "La commande d'impression-objet du débogueur indirectement invoque cette méthode pour produire une description textuelle d'un objet. "Il est bon de remplacer son implémentation dans une sous-classe, mais ce n'est pas un bon choix pour un nom de propriété – bneely

+0

Donc je me suis débarrassé de la" description "(remplacé par "label"), et ajouté le - (vide) dealloc qui était évidemment manquant ... et maintenant ce qui se passe ??? Je ne vais même plus à ma fâcheuse fuite: après l'appel de ma méthode -getAll (appelée dans la méthode -viewDidLoad), je vais immédiatement dans -dealloc, puis mon application plante (... *** __NSAutoreleaseFreedObject(): libération de l'objet précédemment désalloué (0x4b1a3f0) ignoré) ... On dirait que quelque chose d'autre se passe ici ...Je suis très difficile à comprendre, mais c'est si difficile à comprendre :-( – Coriolan

+0

OK, je pense que ça fonctionne enfin ... et je comprends tout à fait ... Ne tenez pas compte de mon commentaire précédent (tout en bricolant avec [[NSString alloc]] initWith ...] vs [NSString stringFrom ...], je me suis retrouvé avec une version envoyée à [NSString stringWith ...] qui plus tard a été suivie par le pool autorelease et donc un crash). J'ai ajouté le -dealloc, il semble bien, pas de fuite, pas de crash.En creusant, j'ai trouvé ce lien très utile expliquant comment Instrument peut aider à résoudre les collisions de la mémoire (http://www.markj.net/iphone-memory-debug-nszombie /) – Coriolan

Questions connexes