委托中的内存泄漏

时间:2010-07-19 18:21:11

标签: iphone objective-c memory-leaks

我的控制器从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 app崩溃了。 如何解决这个问题?

3 个答案:

答案 0 :(得分:2)

返回[list autorelease]是正确的做法。您的问题是您不需要的[body release]。 - [NSString stringWithUTF8String:]返回一个自动释放的NSString。显式[body release]表示列表具有指向解除分配对象的指针。

删除[body release]行并放回return [list autorelease],它应该有效。

您还可以运行静态分析器(Cmd-shift-A),要求编译器找到其他内存管理问题。

答案 1 :(得分:1)

您应该在getChapters中自动发布,并且不应在self.listChapters中发布viewWillAppear。编写[self.something release]并不是一个好主意,因为那时你可能会释​​放一个你仍然分配给该属性的对象。

我强烈建议您阅读memory management rules。它们并不冗长或困难,一旦你通读并理解它们,你甚至不必再考虑这样的事情了。

答案 2 :(得分: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