2009-09-24 6 views
0

J'ai un problème avec ce que je crois être une fuite de mémoire qui, après un certain temps, provoque le ralentissement de mon application. J'ai une section qui a des sections de «réalisateurs de films» avec des rangées de films dans leur section. Pour ce faire, j'appelle un objet de données (et je lui passe l'en-tête de la section) pour retourner les données de cette section et remplir les lignes de la section. Donc j'appelle cet objet plusieurs fois sur la même vue (numberOfRowsInSection, cellForRowAtIndexPath, et didSelectRowAtIndexPath) cela arrive pour chaque section. En regardant les Instruments, je crois que la fuite vient de getDirectorsMovies: theDirector de Movies.m. Quelqu'un peut-il me dire ce que je fais qui provoque cette fuite. Toute aide serait grandement appréciée, j'ai travaillé dessus pendant quelques semaines. Voici un code pour montrer ce que je fais.fuite de mémoire iphone avec uitableview et sqlite

Merci d'avance !!!

//Movies.h 
    #import <Foundation/Foundation.h> 
    #import <sqlite3.h> 
    #import "Movie.h" 

    @interface Movies : NSObject { 
    } 

    - (NSMutableArray *) getDirectorsMovies:(NSString *)theDirector; 

    @end 


    //Movies.m //getDirectorsMovies:(NSString *)theDirector goes to the database, gets the directors movies, and returns them in an array 
    #import "Movies.h" 

    @implementation Movies 

    - (NSMutableArray *) getDirectorsMovies:(NSString *)theDirector 
    { 
     sqlite3 *database; 
     NSString *databaseName = @"Movies.sql"; 
     NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
     NSString *documentsDir = [documentPaths objectAtIndex:0]; 
     NSString *databasePath = [documentsDir stringByAppendingPathComponent:databaseName]; 

      NSMutableArray *theDirectorsMovies = [[NSMutableArray alloc] init]; 

     if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) { 
      const char *sqlStatement = "select * from movies where lastname = ? order by lastname, movie"; 
      sqlite3_stmt *compiledStatement; 
      if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) { 
       sqlite3_bind_text(compiledStatement, 1, [theDirector UTF8String], -1, SQLITE_TRANSIENT); 
       while(sqlite3_step(compiledStatement) == SQLITE_ROW) { 
        NSString *aLastName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)]; 
        NSString *aDirector = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)]; 
        NSString *aMovie = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)]; 

        Movie *movie = [[Movie alloc] initWithName:aMovie lastname:aLastName director:aDirector]; 
        [theDirectorsMovies addObject:movie]; 
        [movie release]; 

       } 
      } 
      sqlite3_finalize(compiledStatement); 
     } 
     sqlite3_close(database); 

     return theDirectorsMovies; 
     [theDirectorsMovies release]; 

    } 


    @end 

// Appel getDirectorsMovies: (NSString *) thedirector

MoviesAppDelegate *appDelegate = (MoviesAppDelegate *)[[UIApplication sharedApplication] delegate]; 
Director *director = (Director *)[appDelegate.director objectAtIndex:indexPath.section];//appDelegate.director IS A MSMutableArray defined in the AppDelegate 

self.theMovies = nil;//THIS IS A MSMutableArray defined in the AppDelegate 
Movies *directorMovies = [[Movies alloc] init]; 
self.theMovies = [directorMovies getDirectorMovies:director.lastname]; 
[directorMovies release]; 

Movie *movie = (Movie *)[theMovies objectAtIndex:indexPath.row]; 
//do whatever with the data 

[movie release]; 

Répondre

4

Vous avez ceci:

return theDirectorsMovies; 
[theDirectorsMovies release]; 

Rien se produit après la déclaration de retour, de sorte que votre appel à release sera jamais arriver. C'est pour cette raison que les AutoreleasePools ont été inventés (and patented). Faites simplement:

return [theDirectorsMovies autorelease]; 

Et votre fuite de mémoire disparaîtra.

+0

J'apprécie votre aide, mais cela a planté l'application. D'autres suggestions? Merci. – GL777

+0

Un certain nombre de choses pourraient planter votre application. Que dit la console? Avez-vous essayé d'allumer des zombies pour voir si vous êtes en train de surcharger un objet (que je parie que vous êtes)? Nous aurions besoin de plus d'informations que "Mon application plante", et il serait bon d'ouvrir probablement une nouvelle question à ce sujet. –

+0

En regardant ce qui précède, je pense que l'application se bloquerait si le code appelant la méthode ne faisait pas de retenue sur NSMutableArray lors de l'appel de la méthode getDirectors. – Openside

0

Il existe un certain nombre de problèmes potentiels ici, il serait utile de voir la méthode init pour Movie comme cela peut être l'endroit où le problème est. Aussi, vous devriez avoir une autorelease sur NSMutableArray.

Dans mon code sqlite J'ai fait la déclaration suivante normalement avant l'appel sqlite3_finalize

sqlite3_clear_bindings(compiledStatement); 

Cet appel éclairci beaucoup de problèmes pour mon code.