iOS: полезность didReceiveMemoryWarning: - PullRequest
12 голосов
/ 24 февраля 2009

Я участвую в процессе разработки для отслеживания сбоев и утечек памяти. В качестве стратегии вы помещаете какие-либо сообщения NSLog или уведомления о таких в didReceiveMemoryWarning:? Документация для этого метода довольно скудна. Правильно ли сказать, что до того, как произойдет сбой, UIViewController вызовет этот метод? Это отправная точка еще до того, как мы начнем работать с инструментами?

Ответы [ 4 ]

28 голосов
/ 24 февраля 2009

ОК, обратите внимание на несколько вещей:

  • didReceiveMemoryWarning будет вызываться до сбоя нехватки памяти. Не другие сбои. Если вы правильно обрабатываете предупреждение и освобождаете память, вы можете избежать нехватки памяти и не потерпеть крах.
  • Вы можете вручную вызвать предупреждение о памяти в симуляторе в меню «Оборудование». Настоятельно рекомендуем сделать это, чтобы проверить вашу обработку didReceiveMemoryWarning.
  • Инструменты помогают отлаживать утечки (хотя и не все) - это не очень полезно для сбоев.
  • Нет, я лично не использую NSLog - я просто делаю остановку предупреждений памяти при отладке.
5 голосов
/ 22 сентября 2011

Если пользователь оставил открытыми некоторые приложения, у вас будет очень мало памяти. Поэтому иногда didReceiveMemoryWarning может вызываться системой только после 1 МБ использования.

Система вызывает этот метод на всех ваших контроллерах представления, если вы поместите NSLog в каждый из ваших контроллеров представления, вы заметите это.

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

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

5 голосов
/ 25 июня 2009

UPDATE Начиная с iOS 6, UIViewController представления больше не выгружаются в ответ на предупреждения памяти. Вместо этого просто делайте все возможное, чтобы освободить любые ресурсы, которые вы можете разумно воссоздать (например, кэшированные данные), когда вызывается didReceiveMemoryWarning.

UPDATE
Я написал свой оригинальный ответ, когда был сердитым молодым человеком; времена изменились и в основном это неправильно.

Если у вас есть приложение с одним контроллером представления и вы получаете предупреждение о памяти, вы ничего не можете сделать. Но все меняется кардинально, если у вас есть несколько контроллеров представления, потому что вы можете выгрузить all состояние, связанное с внешними контроллерами. На самом деле [UIViewController didReceiveMemoryWarning] будет подталкивать вас в правильном направлении, выгружая ваши невидимые виды для вас (сюрприз!). Когда контроллер самого переднего вида отклоняется, базовый вид перезагружается, и самое большее пользователь должен знать только о задержке, даже если внутренне ваше приложение могло выполнить полную перезагрузку.

Это не та деталь, которую вы можете легко модернизировать, вам нужно помнить об использовании памяти с самого начала и спроектировать ваше приложение с несколькими окнами на чисто выгружаемые UIViewController кусочки. На самом деле стоит сохранить ваш код совместимым с симулятором, чтобы использовать функцию предупреждения о памяти.

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

Чтобы воспользоваться этим трюком с памятью, перегрузите методы UIViewController viewDidLoad, viewDidUnload и viewWillUnload (iOS5, полезно, если состояние выгрузки требует, чтобы ваше представление все еще существовало, например, если вы не хотите пропускать текстуры OpenGL и буфер рендеринга, на iOS4 вы можете смоделировать это, перегружая didReceiveMemoryWarning и отслеживая видимость вашего представления) ,

ОРИГИНАЛ, БОЛЬШЕ БИЛИОЗНОГО ОТВЕТА

didReceiveMemoryWarning абсолютно бесполезен.

Нет гарантии, что если вы освободите память (даже всю) что тебя не убьют.

В моем горьком опыте это обычно работает на 2.x / 3.0:

  1. mediaserverd пропускает кучу памяти

  2. мое приложение убивают

К сожалению, жнец никогда не думает об убийстве медиасервера.

Так что, если использование памяти не ваша ошибка, вы действительно только получили два варианта:

  1. попросить пользователя перезагрузиться (пользователь полагает, что это ваша вина, пишет обзор)

  2. надеюсь, что виновник падает (mediaserverd часто обязывает!)

3 голосов
/ 24 февраля 2009

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

Общее правило: у вас есть около 8 МБ ОЗУ для работы. Когда вы приблизитесь к этому, вы можете ожидать, что событие будет возбуждено. Если вы намеренно занимаете столько ОЗУ, у вас должен быть план, чтобы что-то с этим сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...