Подтвердить что ты не робот

IOS: полезность didReceiveMemoryWarning:

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

4b9b3361

Ответ 1

ОК, несколько замечаний:

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

Ответ 2

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

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

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

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

Ответ 3

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

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

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

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

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

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

ОРИГИНАЛЬНЫЙ, БОЛЬШЕ БИОЛОГИЧЕСКИХ ОТВЕТОВ

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

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

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

  • mediaserverd утечки памяти

  • мое приложение убито

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

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

  • попросите пользователя перезагрузиться (пользователь принимает на себя эту ошибку, пишет отчет о сбоях)

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

Ответ 4

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

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