DidReceiveMemoryWarning и viewDidUnload

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

didReceiveMemoryWarning

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

viewDidUnload

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

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

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

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

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

Ответ 1

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

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

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

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

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

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

  • viewDidUnload - освободить любые ссылки на элементы пользовательского интерфейса, загруженные из наконечника. Отпустите все элементы пользовательского интерфейса, созданные мной в viewDidLoad.
  • didReceiveMemoryWarning - освободить любые данные, которые используются в представлении пользовательского интерфейса, который я могу восстановить, если/когда viewDidLoad вызывается снова (или какое-либо другое конкретное событие). НЕ выпускайте ничего, что невозможно воссоздать.

Ответ 2

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

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