iPhone - включая подвиды и возможную утечку памяти?

При написании этих общих утверждений:

UIViewController* viewController = [[UIViewController alloc] initWithNibName:@"myXIB" bundle:nil];
/* do some things with the viewController */
[self.view addSubview:viewController.view];

Мне интересно, есть ли здесь возможная утечка памяти, потому что:

  • viewController не выпущен кодом
  • вызов [выпуска viewController] после его вставки в self.view приводит к сбою приложения
  • viewController не известен self.view, потому что он не вставлен напрямую, поэтому выпуск self.view не должен освобождать viewController

Итак, я вижу здесь утечку памяти, когда viewController никогда не выпускается.

Не могли бы вы поделиться своими экспертными знаниями об этом?

Примечание. Instruments не находит там утечек памяти.


person Oliver    schedule 05.05.2011    source источник


Ответы (4)


Если вы хотите просмотреть как подпредставление, я думаю, что лучше иметь контроллер представления в качестве переменной экземпляра класса и release в dealloc

ОБНОВЛЕНИЕ

Взято из предыдущего вопроса SO

Обнаружение утечек прибора работает путем консервативного сканирования памяти, поиска указателей и построения графа связей между распределениями. Если он находит какие-либо указатели на объект в памяти, к которым можно получить доступ из глобальной переменной или переменной стека, то этот объект не может считаться утечкой.

Инструменты не знают структуру или контекст указателя. Если бы вы использовали malloc(1024) и в этом [переработанном] фрагменте памяти оказалась куча указателей, они бы учитывались, даже если вы никогда больше не будете рассматривать эти указатели как настоящие ссылки.

Так что нет, утечки никогда не могут быть точными на 100%. Кроме того, существует гораздо больше способов утечки памяти, чем фактическая утечка.

person visakh7    schedule 05.05.2011
comment
Instruments не находит там утечки памяти. Ты знаешь почему ? - person Oliver; 05.05.2011
comment
Насколько я знаю из лекций WWDC'10, Instruments гарантирует, что все найденные утечки реальны, но не гарантирует, что все утечки будут найдены. Большинство из них, но не все. - person 5hrp; 05.05.2011

Да, память будет утекать, вы всегда должны освобождать память, выделенную вами. Когда вы добавляете [viewController release], viewController немедленно освобождается, а затем ваше приложение аварийно завершает работу, потому что оно пытается получить доступ к освобожденной памяти. Чтобы предотвратить это, вы должны включить свой viewController в качестве переменной экземпляра вашего класса.

person 5hrp    schedule 05.05.2011

Здесь определенно есть утечка, поскольку вы выделяете новый UIViewController, но никогда не выпускаете его (он не добавляется в пул автовыпуска, когда вы делаете выделение). Вы должны сохранить ссылку на этот объект viewController и освободить его позже.

Как вы сказали, если вы вызываете сразу после [выпуска viewController], это приводит к сбою вашего приложения, потому что вы только что добавили его внутреннее представление в self.view, но счетчик ссылок контроллера, которому принадлежит это представление (viewController), не был увеличен. .

person Moystard    schedule 05.05.2011
comment
Instruments не находит там утечки памяти. Ты знаешь почему ? - person Oliver; 05.05.2011

Метод tableview didselrowatindex является обычным местом, где происходят такие утечки памяти.

Один из способов избавиться от утечек памяти — убедиться, что вы создаете только один экземпляр ViewController, а затем повторно используете его.

Кроме того, этот метод применим не только к созданию и отображению контроллеров представления, но и к чему угодно. Если вы создаете что-либо в коде, например, uilabels и т. д., убедитесь, что вы не создаете несколько экземпляров.

/* код */

// in the interface create an ivar ... or a property if needed
UIViewController *childViewController;

/// затем позже в вашем коде tableview didSelectRow и т. д.

// don't create multiple instances of the VC, rather, check to see if we can reuse one
if (! childViewController)
{
   childViewController = [[UIViewController alloc] init];
}

// do some things with the viewController 
childViewController.someProperty = someValue;
[self.view addSubview:childViewController.view];
person john russell    schedule 01.05.2014