2010-07-19 63 views
0

我控制器獲取數據:內存泄漏從功能delegat

- (NSArray *)getChapters { 
NSMutableArray *list = [[NSMutableArray alloc] init]; //memory leak 
    if (chapter_statement == nil) { 
     const char *sql = "SELECT DISTINCT 'Глава '||chapter FROM verses WHERE book=? ORDER by chapter"; 
     if (sqlite3_prepare_v2(database, sql, -1, &chapter_statement, NULL) != SQLITE_OK) { 
      NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database)); 
     } 
    } 

sqlite3_bind_int(chapter_statement, 1, self.book); 
while (sqlite3_step(chapter_statement) == SQLITE_ROW) {     
    NSString *body = [NSString stringWithUTF8String:(char *)sqlite3_column_text(chapter_statement, 0)];  
    [list addObject:body]; 
    [body release]; 
} 

sqlite3_reset(chapter_statement); 
return list; 
} 

,並在控制器使用它:

- (void)viewWillAppear:(BOOL)animated { 
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 

self.listChapters = [[NSArray alloc] initWithArray:[appDelegate getChapters]]; 

[self.listChapters release]; 

} 

泄漏顯示了內存泄漏:NSMutableArray *list = [[NSMutableArray alloc] init]; 如果我回來像return [list autorelease];應用程序崩潰在viewWillAppear。 如何解決這個問題?

回答

2

返回[list autorelease]是正確的做法。你的問題是你不需要的[body release]。 - [NSString stringWithUTF8String:]返回一個自動發佈的NSString。明確的[body release]意味着列表有指向已釋放對象的指針。

刪除[body release]行並放回return [list autorelease]它應該工作。

您也可以運行靜態分析器(Cmd-shift-A)來要求編譯器查找像這樣的其他內存管理問題。

+0

是的,它的工作,但現在泄漏顯示泄漏 - [NSPlaceholderString initWithBytes:length:encoding:]在基金會 – 2010-07-20 17:52:50

+0

我懷疑泄漏來自其他地方。如果您還沒有,請查看FMDB(http:// gusmueller。com/blog/archives/2008/06/new_home_for_fmdb.html)這是一個Sqlite的基本Cocoa包裝器,可以爲您節省很多管理數據庫調用的麻煩。 – 2010-07-21 05:42:45

0

讓我們算!

1)您分配泄漏陣列的位置:

NSMutableArray *list = [[NSMutableArray alloc] init]; 

retainCount = 1

2)你的陣列添加到另一個陣列的位置:

self.listChapters = [[NSArray alloc] initWithArray:[appDelegate getChapters]]; 

什麼新的數組(listChapters)會保留你的泄漏數組。

retainCount = 2

3)鬆開陣列(listChapters)包含泄漏陣列:

[self.listChapters release]; 

什麼listChapters不也是在這裏釋放所有包含對象一次,包括您的泄漏陣列。此外,所有對您的泄漏陣列的引用在此行後都會丟失。

retainCount = 1

+0

保留計數可能或可能不會絕對爲1或2.永遠不要考慮絕對保留計數,始終考慮增量....即alloc爲+1,self.listChapters = is +1,-release爲-1 。 – bbum 2010-07-19 23:47:55

1

你應該自動釋放在getChapters,你不應該在viewWillAppear釋放self.listChapters。這是寫一個[self.something release]從來沒有好主意,因爲那麼你可能會釋​​放你仍然分配給該屬性的對象。

我強烈建議你閱讀memory management rules。它們並不冗長或難度很大,一旦你閱讀並理解它們,你就再也不會想到這樣的事情了。