didreceivememorywarning вызывает viewdidunload на видимом контроллере представления - PullRequest
0 голосов
/ 10 июля 2011

Я совершенно сбит с толку о том, как обрабатывать предупреждения памяти, когда видимый в данный момент видовой контроллер (superview! = Nil) выгружается.Настройка представляет собой tabbarcontroller в качестве rootViewController, контроллера навигации с контроллером представления, скажем, контроллера представления A. Я помещаю контроллер представления B в стек навигации контроллера представления A.Я имитирую предупреждение памяти.

1) контроллер представления A получает предупреждение памяти, и его представление выгружается, все в порядке.

2) контроллер представления B (видимый в настоящее время) получает предупреждение памяти.я распечатываю его супер-вид.Я даже подтвердил, что контроллер навигации

(gdb) po [[self view] superview]
<UIViewControllerWrapperView: 0x12310c80; frame = (0 64; 1024 655); autoresize = W+H;     layer = <CALayer: 0x12310cb0>>>
(gdb) po [self navigationController]
<UINavigationController: 0x714efd0>
(gdb) po [[[self navigationController] view] superview]
<UIViewControllerWrapperView: 0x740b0c0; frame = (0 0; 1024 719); autoresize = W+H; layer = <CALayer: 0x740b140>>

 /*** can you see how desperate i am? : ) ***/
(gdb) po [[[[[self view] window] rootViewController] view] superview]
<UIWindow: 0x7162910; frame = (0 0; 768 1024); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x7163660>> 

3) Следующее, что я знаю, представление контроллера видимого вида было выгружено (Точка останова в методе контроллера представления viewDidUnload получает удар)

Поскольку я в настоящее время смотрю на этот контроллер представления, его viewDidLoad никогда не будет вызываться снова, если я не вернусь к нему.Кажется, это противоречит многим постам, в которых говорится, что когда superview! = Nil, представление не выгружается !, и я исследовал весь стек!

Чтобы уточнить, я не спрашиваю, чтоделать в viewDidUnload, или какие данные высвобождать, и т. д. и т. д. Я пытаюсь понять, почему платформа отправляет didReceiveMemoryWarning контроллеру представления, который явно все еще является частью иерархии представления.

Мысли

Ответы [ 2 ]

0 голосов
/ 10 июля 2011

Контроллеры представления получают предупреждения памяти, потому что они могут делать что-то потенциально интенсивное использование памяти и, следовательно, должны освободить память. Допустим, у вас есть кэш данных, с которым пользователь может взаимодействовать, но который вы можете перезагрузить при необходимости. Вы хотели бы сбросить это в didReceiveMemoryWarning, потому что было бы лучше перезагрузить по требованию, чем сбой из-за отсутствия mem. Однако вы не должны освобождать представление или все, с чем пользователь в данный момент взаимодействует, в didReceiveMemoryWarning, иначе вы увидите поведение, которое видите.

Кроме того, как указывает заглушка из ответа Paul.s, контроллеры представления получают предупреждения памяти, когда они на самом деле не просматриваются в настоящее время, и поэтому безопасно выпускать их представление. Тем не менее, я бы оставил это реализации супер (как показано на рисунке), поскольку он уже обрабатывался там.

Отпускаете ли вы представление (или его части), когда получаете предупреждение о памяти? Если это так, вы должны вместо этого переместить этот код в viewDidUnload.

0 голосов
/ 10 июля 2011

Для ответа на ваш вопрос вот метод заглушки из шаблона Apple

- (void)didReceiveMemoryWarning
{
  // Releases the view if it doesn't have a superview.
  [super didReceiveMemoryWarning];

  // Release any cached data, images, etc that aren't in use.
}

Это так, что вы можете освободить память, просто потому, что ваш видимость видна, не означает, что она использует все ресурсы, которые она выделила.

...