Как исправить эту утечку памяти вокруг pushViewController? - PullRequest
0 голосов
/ 17 июня 2011

Я запустил инструмент в xcode4, и он сказал мне, что в следующем коде произошли две утечки (отмечено ****). Я думал, что позаботился об освобождении памяти с кодом на pt. А и пт. B.

Я прочитал некоторые связанные темы здесь, но все еще не мог понять, почему и как их исправить.

Другой вопрос, является ли выпуск в пт. А необходимо.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //Get the dialog id
    NSDictionary *rowData = [dialogs objectAtIndex:indexPath.row];
    NSInteger dialogId = [[rowData objectForKey:@"id"] intValue];

    DialogViewController *detailViewController = [[DialogViewController alloc] initWithNibName:@"DialogViewController" bundle:nil];
    detailViewController.dialogId = dialogId;
    NSString *title = [NSString stringWithFormat:@"%d. %@", [[rowData objectForKey:@"id"] intValue], [rowData objectForKey:@"title"]];
                ****** i     6.8%
    [detailViewController.dialogTitle release];             // pt. A
    detailViewController.dialogTitle = [title retain];

    [self.navigationController pushViewController:detailViewController animated:YES];
                ****** i 93.2%
    [detailViewController release];                         // pt. B

}

Большое спасибо заранее! Lu

Ответы [ 2 ]

1 голос
/ 17 июня 2011

Необходимы ли вызовы освобождения / сохранения в точке A, зависит от того, как вы определили свойство dialogTitle.

Если вы определили его как @property (retain), вам не нужно освобождать старое значение или сохранять новое значение, поскольку при назначении значения свойству (retain) оно автоматически сохраняется. Также, когда вы присваиваете новое значение (сохраняющему) свойству, старое значение освобождается, поэтому вам не нужно делать это тоже. Все, что вам нужно в этом случае:

detailViewController.dialogTitle = title;

Если вы определили dialogTitle как (назначить), то вам НЕОБХОДИМО выполнить освобождение / сохранение в точке A.

Что касается точки B, вам нужно освободить ее там, потому что если вы этого не сделаете, ваш объект detailViewController никогда не будет удален. Когда он выделяется / запускается, он получает счет сохранения 1. Когда вы нажимаете контроллер представления, он сохраняется (поэтому теперь имеет счет сохранения 2). Затем вы освобождаете в конце метода, и его счетчик сохранения уменьшается до 1. Затем, когда контроллер навигации, который его содержит, удаляется, он снова освобождается, его счетчик хранения возвращается к 0 и удаляется.

В качестве альтернативы освобождению detailViewController в конце метода, вы можете просто автоматически выпустить его при выделении / инициализации и удалить выпуск в конце метода. Автоматически выпуская его, вы, по сути, отмечаете его автоматическое освобождение при следующей очистке пула автоматического выпуска (что произойдет вскоре после выхода из этого метода)

0 голосов
/ 17 июня 2011

Строка над pushViewController должна быть

detailViewController.dialogTitle = [[title retain] autorelease];

Это также должно работать, если dialagTitle является сохраняемым свойством

detailViewController.dialogTitle = title;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...