Утечки памяти в делегате - PullRequest
0 голосов
/ 19 июля 2010

Мой контроллер получает данные из функции в делегате:

 - (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.Как решить эту проблему?

Ответы [ 3 ]

2 голосов
/ 19 июля 2010

Возвращение [list autorelease] - это правильно. Ваша проблема - [body release], которая вам не нужна. - [NSString stringWithUTF8String:] возвращает автоматически освобожденную строку NSString. Явный [body release] означает, что в списке есть указатели на освобожденные объекты.

Удалите строку [body release] и верните обратно return [list autorelease], и она должна работать.

Вы также можете запустить статический анализатор (Cmd-shift-A), чтобы попросить компилятор найти другие проблемы управления памятью, подобные этой.

1 голос
/ 19 июля 2010

Вы должны автоматически выпустить в getChapters, и вы не должны выпускать self.listChapters в viewWillAppear. Писать [self.something release] почти никогда не стоит, потому что тогда вы потенциально освобождаете объект, который все еще назначен этому свойству.

Я настоятельно рекомендую вам прочитать правила управления памятью . Они не длинные и не сложные, и как только вы прочитаете и поймете их, вам больше никогда не придется думать о чем-то подобном.

0 голосов
/ 19 июля 2010

Давайте посчитаем!

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

...