Что держит на моих контроллерах? - PullRequest
0 голосов
/ 20 сентября 2011

Я создал приложение под бета-версией Xcode 4.3 с использованием шаблона Master / Detail и ARC, но потом обнаружил, что не могу отправить его, поэтому снова перенес его в Xcode 4.2, добавив все управление памятью.Это не утечка, но профилировщик говорит, что растет с каждым разом, когда я посещаю запись подробностей с главного дисплея - каждый контроллер подробностей каждый раз.

Я объявил контроллер как ivar и свойство вГлавный (корневой) контроллер (синтезируется в файле .m):

@interface RootViewController : UITableViewController <NSFetchedResultsControllerDelegate> {
...
    @private
    DetailViewController *detailViewController;
}
...
@property (nonatomic, retain) DetailViewController *detailViewController;
@end

...
@synthasize detailViewController;

Новые экземпляры создаются при выборе элемента основного списка в вызове -tableView: didselectRowAtIndexPath (добавлен NSLog для отображения прогрессивного количества записей):

tableView:didselectRowAtIndexPath call (NSLog's added to show progressive retain count):
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"1 dvc %i",[self.detailViewController retainCount]);
    self.detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
    NSLog(@"2 dvc %i",[self.detailViewController retainCount]);
    NSManagedObject *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath];
    detailViewController.detailItem = selectedObject;    
    [self.navigationController pushViewController:self.detailViewController animated:YES];
    NSLog(@"3 dvc %i",[self.detailViewController retainCount]);
    [self.detailViewController release];
    NSLog(@"4 dvc %i",[self.detailViewController retainCount]);
}

На мой взгляд, это должно было правильно управлять жизненным циклом объекта, и для проверки я поместил еще один NSLog в метод RootViewController -viewWillAppear, чтобы увидеть, что счетчик сохранения каждый раз был корневым (Мастер) вид.Журнал отладки показывает следующее:

2011-09-20 15:17:34.402 ABRA[13133:207] RootViewController viewDidAppear DVC=0
2011-09-20 15:17:38.410 ABRA[13133:207] 1 dvc 0
2011-09-20 15:17:38.411 ABRA[13133:207] 2 dvc 2
2011-09-20 15:17:38.467 ABRA[13133:207] 3 dvc 9
2011-09-20 15:17:38.468 ABRA[13133:207] 4 dvc 8
2011-09-20 15:17:41.889 ABRA[13133:207] RootViewController viewDidAppear DVC=3
2011-09-20 15:17:45.137 ABRA[13133:207] 1 dvc 2
2011-09-20 15:17:45.138 ABRA[13133:207] 2 dvc 2
2011-09-20 15:17:45.330 ABRA[13133:207] 3 dvc 8
2011-09-20 15:17:45.330 ABRA[13133:207] 4 dvc 7

Первый из них хорош.Приложение только что запустилось, поэтому счет сохранения detailViewController равен нулю, поскольку это первая запись в методе tableView.

После выделения счетчик равен 2 (я бы подумал, что он должен быть 1)!

PushViewController увеличивает это значение до 9, а затем в конце метода освобождаю владельца (количество 8).

После того, как контроллер «выскочил» (нажатием левой навигационной панеликнопка бар) и снова отображается Root vew, счетчик по-прежнему равен 3 (один для метода получения / установки и, по-видимому, еще 2 вещи, которые все еще содержат ссылки на него).

Таким образом, когда создается и применяется другой новый экземплярчерез установщик счетчик старого объекта все равно будет равен 2, поэтому он сохраняется, даже если он заменяется новым экземпляром через синтезированный установщик.

Дальнейшие итерации повторяют результат "2,2,8,7,3" до бесконечности.Инструменты не считают это утечкой, но я уверен, что это так, потому что занимаемая площадь увеличивается!

Почему -alloc / -initWithNib приводит к счету сохранения 2, а не 1?Почему толчок увеличивает счет сохранения 7 в первый раз и 6 впоследствии?Как я могу найти то, что удерживает его, когда он должен был быть выпущен?

Ответы [ 2 ]

0 голосов
/ 20 сентября 2011

Я обнаружил, что retainCount обычно ненадежен для устранения утечек.

Вы пробовали это изменение: (В основном, ленивая загрузка dVC?)

tableView:didselectRowAtIndexPath call (NSLog's added to show progressive retain count):
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"1 dvc %i",[self.detailViewController retainCount]);
    if (!self.detailViewController) {
        self.detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
        NSLog(@"2 dvc %i",[self.detailViewController retainCount]);
    }
    NSManagedObject *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath];
    detailViewController.detailItem = selectedObject;    
    [self.navigationController pushViewController:self.detailViewController animated:YES];
    NSLog(@"3 dvc %i",[self.detailViewController retainCount]);
  // release dVC in your dealloc
  //  [self.detailViewController release];
  //  NSLog(@"4 dvc %i",[self.detailViewController retainCount]);

}

Еще лучше, почему бы не использовать IBOutlet для вашего DVC?

0 голосов
/ 20 сентября 2011

Почему -alloc / -initWithNib приводит к счету сохранения 2 и не 1? Почему толчок увеличивает значение счетчика 7 в первый раз а 6 впоследствии? Как я могу найти то, что держит на нем, когда это должен был быть выпущен?

@ свойство (неатомное, сохранить ) DetailViewController * detailViewController;

Это должно ответить на часть вашего ответа. Ваша собственность также сохраняет ваш контроллер представления. Исправьте это и посмотрите, улучшится ли ваша ситуация. (Не задавайте его в свойстве, просто инициируйте локальную переменную и отпустите в конце метода, NavigationController сохранит для вас viewController)

Трудно ответить на 2-ю часть вашего вопроса просто потому, что мы не знаем, что происходит со свойством detailItem в detailViewController. Просто исправьте вышеизложенное и отредактируйте свой ответ с прогрессом.

...