【问题标题】:sqlite3 - stringWithUTF8String is leaking!sqlite3 - stringWithUTF8String 正在泄漏!
【发布时间】:2010-06-05 06:56:08
【问题描述】:

如果有人可以帮助我解决我的泄漏问题,我将不胜感激。泄漏发生在:aImage、aCategory、aDescription、类别和类别。我在 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];
}

【问题讨论】:

  • 这些字符串没有泄漏。事实上,你过度释放它们。
  • 究竟是什么让您认为您正在泄漏字符串?鉴于上面的代码,你是在过度释放你的字符串,而不是泄漏它们。

标签: objective-c memory-leaks


【解决方案1】:

如果多次调用该方法,则字符串会泄漏,因为您需要释放以前的值。您还过度释放了 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];
    }

}

【讨论】:

  • 我试过这样,但它一直在泄漏(我保留了字符串)。 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString *myString = [NSString stringWithFormat:@"%@%@%@", @"select * from description where category ='", [category the_category], @"'"]; char *composeSQL = ( char *) [myString cStringUsingEncoding:NSISOLatin1StringEncoding]; readDescription=[[ReadFromDatabase alloc] init]; [readDescription readListFromDatabase:composeSQL];描述=[读取描述类别]; self.messageDetailViewController.arraySelectedCategoryValue = [描述副本]; [池释放];
  • 我已经更新了我的答案,包括在实例变量中释放以前的值。我看不出字符串泄漏的任何其他方式。
【解决方案2】:

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

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

【讨论】:

  • 我包括[类别发布];但它仍然泄漏。似乎泄漏问题比编写整个应用程序更难解决。
  • 为什么当我在循环中包含 [aImage autorelease] 时应用程序会终止(如果 [aImage release] 也会终止)?
  • 你问的最后一个问题很容易回答。这是因为您没有 aImage。我认为您需要重新阅读 Cocoa 内存管理规则developer.apple.com/mac/library/documentation/cocoa/Conceptual/…
  • @Darko Hebrang:它终止是因为您的字符串没有泄漏。如果您想稍后使用它们,您需要保留或复制它们。请务必阅读 JeremyP 发布的规则。
【解决方案3】:

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

【讨论】:

    【解决方案4】:

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

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

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

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

    解决了问题

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-05
      • 1970-01-01
      • 2011-10-20
      • 1970-01-01
      • 2011-09-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多