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

DidReceiveMemoryWarning, viewDidUnload и dealloc

Я просмотрел множество сообщений, моих книг и Apple Developer и получил большую часть понимания, которое мне нужно использовать. Я был бы очень благодарен, если какой-нибудь человек может подтвердить, что у меня все в порядке (или исправить), а также ответить на два вопроса.

Большое спасибо,

Крис.

Порядок сообщений Как правило, сообщения отображаются в следующем порядке:

  • didReceiveMemoryWarning

  • viewDidUnload (что может быть вызвано 1) - очевидно, применимо только к классам View Controller.

  • dealloc

didReceiveMemoryWarning

Вызывается, когда система неактивна в памяти.

По умолчанию контроллеры просмотра регистрируются для уведомлений о предупреждении памяти и в методе шаблона, вызов [super didReceiveMemoryWarning] освобождает представление, если у него нет супервизора, что является способом проверки видимости вида или нет. Он освобождает представление, устанавливая его свойство равным нулю.

Действие. Отпустите все, что вам не нужно, скорее всего, будет уничтожено то, что вы могли установить в viewDidLoad. Не выпускайте элементы пользовательского интерфейса, поскольку они должны быть выпущены функцией viewDidUnload.

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

viewDidUnload

Вызывается всякий раз, когда для невидимого свойства View Controller View установлено значение nil, либо вручную, либо чаще всего через didReceiveMemoryWarning.

Метод viewDidUnload существует, чтобы вы могли: - очистить все остальное, что вы хотели бы, чтобы сохранить дополнительную память или - если вы сохранили некоторые IBOutlets, чтобы освободить память, которая иначе не была бы выпущена при разгрузке представления.

Действие - как правило, любые IBOutlets, которые вы выпускаете в dealloc, также должны быть освобождены (и ссылки установлены на нуль) в этом методе. Обратите внимание, что если свойства будут сохранены, то их установка будет равна нулю.

dealloc

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

Действие - освободить все объекты, сохраненные классом, включая, но не ограничиваясь, все свойства с сохранением или копированием.

Контроллеры просмотров и памяти

Вопрос 2 - Выводит ли вид снимок из памяти?

4b9b3361

Ответ 1

Некоторые исправления и предложения:

  • didReceiveMemoryWarning практики

Как вы сказали, реализация по умолчанию контроллера didReceiveMemoryWarning освобождает его представление, если оно "безопасно". Хотя из документов Apple не ясно, что означает "безопасно это сделать", оно общепризнано, поскольку оно не имеет супервизора (таким образом, в настоящее время нет видимого представления), а его метод loadView может перестроить весь вид без проблем.

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

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

Поэтому в вашем didReceiveMemoryWarning сначала вызовите реализацию суперкласса, и если его представление будет выгружено, отпустите пользовательские данные, потому что вы знаете, что loadView и viewDidLoad будут снова вызваны. Например,

- (void)didReceiveMemoryWarning {
    /* This is the view controller method */
    [super didReceiveMemoryWarning];
    if (![self isViewLoaded]) {
        /* release your custom data which will be rebuilt in loadView or viewDidLoad */
    }
}

Соблюдайте осторожность, чтобы не использовать self.view == nil, потому что self.view предполагает, что представление необходимо кому-то и немедленно загрузит представление.

  • viewDidUnload метод

viewDidUnload вызывается, когда контроллер просмотра выгружает представление из-за предупреждения о памяти. Например, если вы удалите представление из супервизора и установите для свойства view контроллера значение nil, метод viewDidUnload будет вызываться не. Тонкая точка заключается в том, что даже если представление диспетчера представлений уже выпущено и установлено на нуль к моменту, когда контроллер получает didReceiveMemoryWarning, так что на самом деле нет никакого вида для выгрузки для контроллера, viewDidUnload будет вызываться, если вы вызовите реализацию суперкласса didReceiveMemoryWarning.

Вот почему не рекомендуется вручную устанавливать свойство view контроллера представления на nil. Если вы это сделаете, вы можете отправить сообщение viewDidUnload. Я думаю, ваше понимание viewDidUnload более желательно, но, по-видимому, это не текущее поведение.

  • Контроллеры отображения всплывающих окон

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

Если вы имеете в виду выскочить из UINavigationController, это фактически уменьшит счетчик хранения самого контроллера представления. Если контроллер просмотра не сохраняется другим объектом, он будет освобожден, желательно с его представлением. Как я объяснил, на этот раз вызывается viewDidUnload not.

  • Другие...

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

Чтобы убедиться, что сам контроллер представления обычно не освобождается по умолчанию из-за предупреждения о памяти.

Ответ 2

didReceiveMemoryWarning

...

Действие. Отпустите все, что вам не нужно, скорее всего, отмените то, что вы могли настроить в viewDidLoad.

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

viewDidUnload

...

Действие - как правило, любые IBOutlets, которые вы выпускаете в dealloc, также должны быть освобождены (и ссылки установлены на нуль) в этом методе. Обратите внимание, что если свойства будут сохранены, то их установка будет равна нулю.

Правильно. Как правило, все, что вы создаете в viewDidLoad и все IBOutlets, объявленные как retain, должно быть выпущено и установлено здесь nil.

dealloc

...

Действие - освободить все объекты, сохраненные классом, включая, но не ограничиваясь, все свойства с сохранением или копированием.

Правильно. Стоит отметить, что это включает все объекты, которые вы обрабатываете в viewDidUnload, потому что последний неявно не вызван в процессе dealloc (AFAIK, не совсем уверен). Поэтому важно установить все объекты выпусков на nil в viewDidUnload, потому что в противном случае вы рискуете отпустить что-то дважды (сначала в viewDidUnload, затем снова в dealloc), если вы установите указатель на nil, релиз в dealloc не будет иметь эффекта).

Контроллеры отображения и памяти

Вопрос 2 - Выводит ли вид снимок из памяти?

Не обязательно. Это деталь реализации, о которой вы не должны беспокоиться. Независимо от нынешней практики Apple может изменить ее в следующей версии.

Ответ 4

Форма iOS 6 и далее, как мы можем проверить, загружен ли просмотр снова. Поскольку "viewDidUnload" устарел. Вы уверены, что "loadView" и "viewDidload" вызовут, если представление будет удалено после предупреждения "didReceiveMemoryWarning".