2010-06-05 22 views
3

如果有人能幫助我解決泄漏問題,我將不勝感激。泄漏發生在:aImage,aCategory,aDescription,類別和類別。我釋放他們的dealloc,但顯然這還不夠:sqlite3 - stringWithUTF8String泄漏!

-(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]; 
} 
+1

。事實上,你是過度釋放他們。 – 2010-06-05 07:00:10

+0

究竟是什麼讓你覺得自己在漏電?鑑於上面的代碼,你過度釋放你的字符串,而不是泄漏它們。 – 2010-06-05 15:56:39

回答

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]; 
    } 

} 
+0

我試過這樣,但它一直在泄漏(我保留了字符串)。 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; \t 的NSString *的myString = [NSString的stringWithFormat:@ 「%@%@%@」,@ 「從描述選擇*,其中類別= '」,[類別the_category],@ 「'」]; char * composeSQL =(char *)[myString cStringUsingEncoding:NSISOLatin1StringEncoding];readDescription = [[ReadFromDatabase alloc] init]; [readDescription readListFromDatabase:composeSQL]; description = [readDescription categories]; \t self.messageDetailViewController.arraySelectedCategoryValue = [描述副本]; \t [pool release]; – 2010-06-05 09:15:52

+1

我已經更新了我的答案,包括在實例變量中釋放先前的值。我看不到任何其他方式的字符串泄漏。 – 2010-06-05 11:20:31

1

是你貼被稱爲不止一次在同一對象上的方法是什麼?如果是,則來自第一次調用的類別將因每次調用readListFromDatabase:時被覆蓋而泄漏。嘗試:

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

我包括[類別發佈];但它仍然泄漏。 似乎泄漏問題比編寫整個應用程序更難解決。 – 2010-06-05 09:59:59

+0

當我在循環中包含[aImage autorelease]時,爲什麼應用程序會終止(它也會在[aImage release]時終止)? – 2010-06-05 10:16:30

+0

你問的最後一個問題很容易回答。這是因爲你不擁有一個圖像。我認爲你需要引導Cocoa內存管理規則http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-BAJHFBGH – JeremyP 2010-06-05 10:21:28

0

爲什麼該應用程序終止時我有[aImage自動釋放]在循環(也終止,如果[aImage發佈])?

0

有點晚了,但我正在更新一個老項目,碰到類似的問題就來了。 我有一個不正確的方便方法!

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

分析說我有內存泄漏,但一個簡單的重命名,以

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

解決這些字符串不泄漏問題