views:

417

answers:

1

Hi All,

I am having a problem with what I believe is a memory leak which after some time is causing my app to slow down. I have a sectioned uitableview that has sections of 'movie directors' with rows of thier movies in their particular section. To do this I am calling a data object (and passing it the section header) to return that section's data and populate the section rows. So I am calling that object a few times on the same view(numberOfRowsInSection, cellForRowAtIndexPath, and didSelectRowAtIndexPath) this happens for each section. Looking at Instruments, I believe the leak is coming from getDirectorsMovies:theDirector from Movies.m. Can anyone tell me what I am doing that is causing this leak. Any help would be greatly appreciated, I've been working on this for a few weeks. Below is some code to show what I am doing.

Thanks in advance!!!

    //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

//Calling 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];
+3  A: 

You have this:

return theDirectorsMovies;
[theDirectorsMovies release];

Nothing happens after the return statement, so your call to release will never happen. It was for this very reason that AutoreleasePools were invented (and patented). Simply do:

return [theDirectorsMovies autorelease];

And your memory leak will go away.

Dave DeLong
I appreciate your help, but doing that crashed the app. Any other suggestions? Thanks.
GL777
A whole number of things could crash your app. What does the console say? Have you tried turning on zombies to see if you're overreleasing an object (which I'll bet you are)? We'd need more information than "My app is crashing", and it'd be good to probably open a new question about it.
Dave DeLong