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

Как реализовать didReceiveMemoryWarning?

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

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

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

Я также где-то читал, что если представление для этого контроллера не видно, будет вызван метод setView с параметром nil, и если есть некоторые переменные на выходе, прикрепленные к просмотру, будет проблема при удалении их.

Итак, со всеми этими фондами, что лучше всего подходит для работы с низким уровнем памяти, вызванным Iphone, реализовав методы didReceiveMemoryWarning и viewDidUnload.

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

спасибо.

4b9b3361

Ответ 1

Один пример, который я публикую... который я скопировал из somwhere... это может дать вам некоторую идею...

- (void)didReceiveMemoryWarning {

    // Release anything that not essential, such as cached data (meaning
    // instance variables, and what else...?)

    // Obviously can't access local variables such as defined in method
    // loadView, so can't release them here We can set some instance variables
    // as nil, rather than call the release method on them, if we have defined
    // setters that retain nil and release their old values (such as through use
    // of @synthesize). This can be a better approach than using the release
    // method, because this prevents a variable from pointing to random remnant
    // data.  Note in contrast, that setting a variable directly (using "=" and
    // not using the setter), would result in a memory leak.
    self.myStringB = nil;
    self.myStringD = nil;
    [myStringA release];// No setter defined - must release it this way
    [myStringC release];// No setter defined - must release it this way

    /* 3. MUST CONFIRM: NOT necessary to release outlets here - See override of
       setView instead.
    self.labelA = nil;
    self.imageViewA = nil;
    self.subViewA = nil;
     */
    // Releases the view if it doesn't have a superview
    [super didReceiveMemoryWarning];
}

Ответ 2

Предупреждения о памяти - это сигнал для вас, что вы должны распоряжаться любыми ресурсами, которые не являются абсолютно критичными. Большинство ваших контроллеров будут висящими на кэшах данных, промежуточных данных или других битах и ​​фрагментах, часто для экономии перерасчета. Когда они получают предупреждения о памяти, они должны начать промывать все, что им не нужно немедленно, чтобы работать.

Как вы определяете, что является "критическим", полностью зависит от вашего дизайна приложения. Например, игра OpenGL может определять, что текстуры в настоящее время на экране являются ценными и скрытыми текстурами, которые не видны, или данные уровня, которые находятся за пределами текущей области воспроизведения. Приложение с расширенными сеансовыми журналами (например, IRC-клиент) может вывести их из памяти и на диск.

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

Ответ 3

В iOS 5 и ранее.

Когда контроллер получит предупреждение о памяти, будет вызываться doReceiveMemoryWarning. В то время, если представление контроллера отсутствует в иерархии представлений, представление будет установлено на nil, и viewDidUnload будет автоматически вызван. Итак, вещи, которые мы должны делать в viewDidUnload, освобождают подзадачу, созданную в viewDidLoad или созданную из Nib. Вот так:

- (void)viewDidUnload
{
    self.subView = nil;
    self.subViewFromNib = nil;
}

- (void)didReceiveMemoryWarning
{
    self.someDataCanBeRecreatedEasily = nil;
    [super didReceiveMemoryWarning];
}

На iOS6.

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

- (void)didReceiveMemoryWarning
{
    if ([self isViewLoaded] && [self.view window] == nil) {
        self.view = nil;
        self.subView = nil;
        self.subViewFromNib = nil;
    }
    self.someDataCanBeRecreatedEasily = nil;
    [super didReceiveMemoryWarning];
}

Обратите внимание, что мы не называем [self view], прежде чем знаем, что представление загружено. потому что этот метод автоматически загрузит представление, если представление не загружено.

Обратите внимание, что мы можем освободить представление, только когда представление не добавлено в окно.

Ответ 4

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

Ответ 5

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

Ответ 6

К моему удивлению, только несколько приложений в официальных образцах iPhone внедряют didReciveMemoryWarning. Вы можете использовать пример iPhoneCoreDataRecipes в качестве ссылки.

Некоторые примеры (например, TableViewSuite) даже делают что-то еще; -)