sqlite3 - stringWithUTF8String正在泄漏!

时间:2010-06-05 06:56:08

标签: objective-c memory-leaks

如果有人能帮我解决漏水问题,我将不胜感激。泄漏发生在:aImage,aCategory,aDescription,category和categories。我以dealloc发布它们,但显然这还不够:

-(void) readListFromDatabase:(char *) sqlStatement {
    // Setup some globals
    databaseName = @"mydatabase.sql";

    // Get the path to the documents directory and append the databaseName
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDir = [documentPaths objectAtIndex:0];
    databasePath = [documentsDir stringByAppendingPathComponent:databaseName];

    // Setup the database object
    sqlite3 *database;

    // Init the categories Array
    categories = [[NSMutableArray alloc] init];

    // Open the database from the users filessytem
    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
        // Setup the SQL Statement and compile it for faster access
        sqlite3_stmt *compiledStatement;
        if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
            // Loop through the results and add them to the feeds array
            while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
                // Read the data from the result row
                aImage = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
                aCategory = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
                aDescription = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];

                // Create a new category object with the data from the database             
                category=[[Category alloc] initWithName:aImage category_name:aCategory description_text:aDescription];

                // Add the category object to the categories Array
                [categories addObject:category];

                [category release];
            }
        }
        // Release the compiled statement from memory
        sqlite3_finalize(compiledStatement);
    }
    sqlite3_close(database);

}

- (void)dealloc {
    [databaseName release];
    [databasePath release];
    [categories release];
    [aImage release];
    [aCategory release];
    [aDescription release];
    [category release];


    [super dealloc];
}

4 个答案:

答案 0 :(得分:2)

如果多次调用该方法,则字符串将泄漏,因为您需要释放以前的值。你也在dealloc中过度发布字符串,因为你从未保留它们。你应该写这样的作业:

[aImage release];
aImage = [[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)] retain];

这些字符串可能泄漏的唯一另一种方式是,如果从线程调用此方法并且您没有创建自动释放池。

如果从新线程调用该方法,则需要一个自动释放池:

- (void)myThreadFunction {
    NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init];
    try {
        // ...
        [self readListFromDatabase:whatever];
        // ...
    } @finally {
        [pool release];
    }

}

答案 1 :(得分:1)

您发布的方法是否在同一个对象上被多次调用?如果是,则第一次调用的类别将泄漏,因为每次调用readListFromDatabase:时都会覆盖它。尝试:

// Init the categories Array
[categories release];
categories = [[NSMutableArray alloc] init];

答案 2 :(得分:0)

为什么当我在循环中包含[aImage autorelease]时应用程序终止(如果[aImage release]它也会终止)?

答案 3 :(得分:0)

有点晚了,但我正在更新一个旧项目并遇到了类似的问题。 我有一个错误命名的便利方法!

- (NSString *)initStringFromPosition:(int)index {
    char *str = (char *)sqlite3_column_text(init_statement, index);
    return (str) ? [NSString stringWithUTF8String:str] : @"";
}

分析说我有内存泄漏,但是简单地重命名为

- (NSString *)stringFromPosition:(int)index {

解决了问题