【问题标题】:iphone memory leak with uitableview and sqlite使用uitableview和sqlite的iphone内存泄漏
【发布时间】:2010-12-01 04:16:13
【问题描述】:

我有一个问题,我认为是内存泄漏,一段时间后导致我的应用程序变慢。我有一个分段的 uitableview,其中包含“电影导演”的部分,在他们的特定部分中有一排他们的电影。为此,我调用了一个数据对象(并将节标题传递给它)以返回该节的数据并填充节行。所以我在同一个视图(numberOfRowsInSection、cellForRowAtIndexPath 和 didSelectRowAtIndexPath)上多次调用该对象,每个部分都会发生这种情况。查看 Instruments,我相信泄漏来自 getDirectorsMovies:theDirector from Movies.m。谁能告诉我我在做什么导致这个泄漏。任何帮助将不胜感激,我已经为此工作了几个星期。下面是一些代码来显示我在做什么。

提前致谢!!!

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

//调用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];

【问题讨论】:

    标签: iphone sqlite uitableview memory-management memory-leaks


    【解决方案1】:

    你有这个:

    return theDirectorsMovies;
    [theDirectorsMovies release];
    

    什么都没有在 return 语句之后发生,因此您对 release 的调用将永远不会发生。正是出于这个原因,发明了 AutoreleasePools (and patented)。只需这样做:

    return [theDirectorsMovies autorelease];
    

    你的内存泄漏就会消失。

    【讨论】:

    • 感谢您的帮助,但这样做会使应用程序崩溃。还有其他建议吗?谢谢。
    • 很多事情都可能使您的应用程序崩溃。控制台说什么?你有没有试过打开僵尸看看你是否过度释放了一个物体(我敢打赌你是)?我们需要比“我的应用程序崩溃”更多的信息,并且最好提出一个关于它的新问题。
    • 看上面我认为如果调用该方法的代码在调用 getDirectors 方法时没有对 NSMutableArray 进行保留,应用程序会崩溃。
    【解决方案2】:

    这里有许多潜在问题,查看 Movie 的 init 方法会很有用,因为这可能就是问题所在。你也应该在 NSMutableArray 上有一个自动释放。

    在我的 sqlite 代码中,我通常在 sqlite3_finalize 调用之前有以下语句

    sqlite3_clear_bindings(compiledStatement);
    

    那次调用为我的代码解决了很多问题。

    【讨论】:

      猜你喜欢
      • 2010-12-18
      • 1970-01-01
      • 2013-12-24
      • 1970-01-01
      • 2011-06-11
      • 1970-01-01
      • 1970-01-01
      • 2011-01-30
      • 1970-01-01
      相关资源
      最近更新 更多