didReceiveMemoryWarning и viewDidUnload

Из Руководства по программированию контроллера View от Apple / Эффективное управление памятью;

didReceiveMemoryWarning

Используйте этот метод, чтобы освободить все некритические пользовательские структуры данных, связанные с вашим контроллером представления. Хотя вы не стали бы использовать этот метод для освобождения ссылок на объекты просмотра, вы можете использовать его для освобождения любых структур данных, связанных с представлением, которые вы еще не выпустили в своем методе viewDidUnload. (Сами объекты представления всегда должны быть освобождены в методе viewDidUnload.)

viewDidUnload

Вы можете использовать метод viewDidUnload для освобождения любых данных, относящихся к представлению, которые можно легко воссоздать, если представление снова загружается в память. Однако, если воссоздание данных может занять слишком много времени, вам не нужно выпускать соответствующие объекты данных здесь. Вместо этого вам следует рассмотреть возможность выпуска этих объектов в методе didReceiveMemoryWarning.

http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/BasicViewControllers/BasicViewControllers.html

  1. Для didReceiveMemoryWarning рекомендуется освободить некритические структуры данных. Итак, что критично, а что некритично?

  2. Кроме того, в нем говорится о выпуске того, что мы еще не выпустили в viewDidUnload. Но когда появляется предупреждение о памяти, вызывается didReceiveMemoryWarning и представление может быть выгружено, тогда вызывается viewDidUnload. Итак, речь идет о перемещении этих кодов в метод предыдущего события (didReceiveMemoryWarning) или мне что-то не хватает в порядке событий?

  3. Для viewDidUnload рекомендуется легко воссоздавать данные при перезагрузке представления. Итак, если представление используется и не может быть выгружено, почему мы будем выпускать трудоемкие данные в didReceiveMemoryWarning? После выпуска этих данных, когда пользователь пытается что-то сделать в текущем представлении, их загрузка также займет много времени.


person lockedscope    schedule 04.12.2010    source источник


Ответы (2)


Прежде всего, это всего лишь рекомендации, поэтому, если вы не думаете, что есть смысл выпускать что-то в didReceiveMemoryWarning, не делайте этого. Но имейте в виду, что если ваше приложение в первую очередь вызывает предупреждение о памяти, оно в конечном итоге просто будет прекращено ОС.

Re (1): Критическое или некритическое - это полностью ваш выбор. Только вы действительно можете определить, какие данные вы считаете важными. Хотя это, вероятно, будет тесно связано с вашим (3), то есть то, что легко воссоздать, вероятно, не слишком критично.

Re (2): Я не думаю, что это утверждение относится к порядку звонков. Как вы уже поняли, в общем случае viewDidUnload будет вызываться после didReceiveMemoryWarning (поскольку didReceiveMemoryWarning может вызвать вызов viewDidUnload). Например, в viewDidUnload ссылки на элементы пользовательского интерфейса будут освобождены из пера. Так что не выпускайте их также в didReceiveMemoryWarning.

По поводу (3): Если представление уже используется и поэтому не может быть выгружено, тогда да, очевидно, нет смысла выпускать его в didReceiveMemoryWarning. Однако у вас могут быть случаи, когда представление не может быть выгружено, но известно, что оно не отображается (не очень нормально), и в этом случае может иметь смысл выгрузить данные и воссоздать их, когда представление снова станет видимым. .

Кроме того, я согласен с замечаниями «Вместо этого вам следует рассмотреть ...» немного странно, но, опять же, я думаю, что рекомендация о публикации данных в didReceiveMemoryWarning проистекает из того факта, что если вы получаете эти предупреждения, то ваши собственные приложение может быть закрыто. Таким образом, хотя в настоящее время viewDidUnload, вероятно, всегда вызывается в результате предупреждения памяти, это может не всегда иметь место в будущем, и поэтому концептуально имеет смысл выпустить данные в самом didReceiveMemoryWarning. В didReceiveMemoryWarning вы ЗНАЕТЕ, что есть нехватка памяти, в viewDidUnload вы не можете. Так что, хотя воссоздание данных будет стоить дорого, это может быть лучше, чем прекращение работы вашего приложения. Для пользователя это будет выглядеть так, как если бы приложение разбилось.

Мой личный подход к этим методам обычно таков:

  • viewDidUnload - Освободите все ссылки на элементы пользовательского интерфейса, загруженные из пера. Освободите все элементы пользовательского интерфейса, которые я создал сам в viewDidLoad.
  • didReceiveMemoryWarning - Освободите все данные, которые используются в представлении пользовательского интерфейса, которые я могу воссоздать, если / когда viewDidLoad вызывается снова (или какое-либо другое событие, специфичное для приложения). НЕ выпускайте ничего, что я не могу воссоздать.
person imaginaryboy    schedule 04.12.2010
comment
как вы указываете, они называют это аналогом, но он не вызывается без предупреждения памяти. - person lockedscope; 04.12.2010
comment
значит, вы имеете в виду, что модальные представления не видны (не очень-то нормально), не так ли? есть ли другие случаи? - person lockedscope; 04.12.2010
comment
Вид в полноэкранном модальном окне может быть одним случаем, да. Не уверен, есть ли другие случаи. - person imaginaryboy; 04.12.2010
comment
поскольку именно последний вызов обычно запускает первый. последний запускает первый ?? - person lockedscope; 06.12.2010
comment
Я уточнил комментарий: didReceiveMemoryWarning может вызывать вызов viewDidUnload. - person imaginaryboy; 06.12.2010
comment
viewDidUnload устарел в iOS 6, просто скажу. - person Dan Abramov; 21.09.2012

Приложения, которые я создаю, требуют много графики как с точки зрения хрома макета, так и с точки зрения изображений, связанных с данными, которые я загружаю и отображаю.

Мои didReceiveMemoryWarning методы ВСЕ предназначены для определения изображений, которые я храню в памяти, но не отображаемых в данный момент, и удаления их из памяти. Другая часть этого заключается в том, что перед отображением изображения вам необходимо проверить, есть ли оно еще, и выполнить ленивую загрузку, если нет.

person Dan Ray    schedule 06.12.2010