Управление ресурсами в поле зрения контроллеры

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

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

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

Инициализация контроллера представления

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

Инициализация контроллера представления, загруженного от раскадровки

При создании контроллера представления в раскадровке атрибуты, которые Вы конфигурируете в Интерфейсном Разработчике, сериализируются в архив. Позже, когда контроллер представления инстанцируют, этот архив загружается в память и обрабатывается. Результатом является ряд объектов, атрибуты которых соответствуют тем, Вы устанавливаете в Интерфейсном Разработчике. Архив загружается путем вызова контроллера представления initWithCoder: метод. Затем awakeFromNib метод вызывают на любом объекте, реализующем тот метод. Вы используете этот метод для выполнения любых шагов конфигурации, требующих, чтобы уже были инстанцированы другие объекты.

Для больше при архивации и архивации, см. Руководство по программированию Архивов и Сериализации.

Инициализация контроллеров представления программно

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

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

Когда к Его Представлению Получают доступ, Контроллер Представления Инстанцирует Своей Иерархии Представления

Каждый раз, когда некоторая часть Вашего приложения просит у контроллера представления свой объект представления и что объект в настоящее время не находится в памяти, контроллер представления загружает иерархию представления в память и хранит его в view свойство для использования в будущем. Шаги, происходящие во время цикла загрузки:

  1. Контроллер представления вызывает loadView метод. Реализация по умолчанию loadView метод делает одну из двух вещей:

    • Если контроллер представления связан с раскадровкой, он загружает представления из раскадровки.

    • Если контроллер представления не связан с раскадровкой, пустым UIView объект создается и присваивается view свойство.

  2. Контроллер представления вызывает viewDidLoad метод, позволяющий Вашему подклассу выполнить любые дополнительные задачи времени загрузки.

Рисунок 4-1 показывает визуальное представление цикла загрузки, включая несколько из методов, которые вызывают. Ваше приложение может переопределить обоих loadView и viewDidLoad методы по мере необходимости для упрощения поведения Вы хотите для своего контроллера представления. Например, если Ваше приложение не использует раскадровки, но Вы хотите, чтобы дополнительные представления были добавлены к иерархии представления, Вы переопределяете loadView метод для инстанцирования этих представлений программно.

Рисунок 4-1  , Загружающий представление в память

Загрузка представления контроллера представления от раскадровки

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

Создание представления в интерфейсном разработчике

Интерфейсный Разработчик является частью XCode и обеспечивает интуитивный способ создать и сконфигурировать представления для Ваших контроллеров представления. Используя Интерфейсного Разработчика, Вы собираете представления и средства управления путем управления ими непосредственно, перетаскивания их в рабочую область, расположения их, калибровки их и изменения их атрибутов с помощью окна инспектора. Результаты тогда сохраняются в файле раскадровки, хранящем набор объектов, которые Вы собрали вместе с информацией обо всех настройках, которые Вы сделали.

Конфигурирование атрибутов дисплея представления в интерфейсном разработчике

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

Конфигурирование действий и выходов для контроллера представления

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

Перечисление 4-1 показывает объявление пользовательского MyViewController два пользовательских выхода класса (определяемый IBOutlet ключевое слово) и единственный метод действия (определяемый IBAction возвратите тип). Заявления сделаны в категории в файле реализации. В то время как метод действия реагирует на касания в кнопке, выходы хранят ссылки на кнопку и текстовое поле в раскадровке.

  Объявление класса контроллера представления Listing 4-1 Custom

@interface MyViewController()
@property (nonatomic) IBOutlet id myButton;
@property (nonatomic) IBOutlet id myTextField;
 
- (IBAction)myAction:(id)sender;
@end

Рисунок 4-2 показывает соединения, которые Вы создали бы среди объектов в таком MyViewController класс.

  Соединения рисунка 4-2 в раскадровке

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

Создание представления программно

Если Вы предпочитаете создавать представления программно, вместо того, чтобы использовать раскадровку, Вы делаете так путем переопределения контроллера представления loadView метод. Ваша реализация этого метода должна сделать следующее:

  1. Создайте корневой объект представления.

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

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

  2. Создайте дополнительные подпредставления и добавьте их к корневому представлению.

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

    1. Создайте и инициализируйте представление.

    2. Добавьте представление к родительскому представлению с помощью addSubview: метод.

  3. Если Вы используете автоматическое расположение, присваиваете достаточные ограничения каждому из представлений, Вы просто создали для управления позицией и размером представлений. Иначе, реализуйте viewWillLayoutSubviews и viewDidLayoutSubviews методы для корректировки кадров подпредставлений в иерархии представления. Посмотрите Изменение размеров Представлений Контроллера Представления.

  4. Присвойте корневое представление представление свойство из Вашего контроллера представления.

Перечисление 4-2 показывает реализацию в качестве примера loadView метод. Этот метод создает пару пользовательских представлений в иерархии представления и присваивает их контроллеру представления.

  Создание перечисления 4-2 просматривает программно

- (void)loadView
{
    CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame];
    UIView *contentView = [[UIView alloc] initWithFrame:applicationFrame];
    contentView.backgroundColor = [UIColor blackColor];
    self.view = contentView;
 
    levelView = [[LevelView alloc] initWithFrame:applicationFrame viewController:self];
    [self.view addSubview:levelView];
}

Управление памятью эффективно

Когда дело доходит до контроллеров представления и управления памятью, существует две проблемы для рассмотрения:

Несмотря на то, что некоторые аспекты выделения памяти являются строго Вашими для решения, UIViewController класс обеспечивает некоторые методы, обычно имеющие некоторое соединение с задачами управления памятью. Таблица 4-1 перечисляет места в Вашем объекте контроллера представления, где Вы, вероятно, выделите или освободите память, вместе с информацией о том, что необходимо делать в каждом месте.

Табличные 4-1  Места, чтобы выделить и освободить память

Задача

Методы

Обсуждение

Выделение структур критических данных требуется Вашим контроллером представления

Методы инициализации

Ваш пользовательский метод инициализации (называют ли это init или что-то еще), всегда ответственно за помещение Вашего объекта контроллера представления в известном хорошем состоянии. Это включает выделение независимо от того, что структуры данных необходимы для обеспечения правильного функционирования.

Создание Ваших объектов представления

loadView

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

Создание пользовательских объектов

Пользовательские свойства и методы

Несмотря на то, что Вы свободны использовать другие проекты, рассмотрите использование образца, подобного loadView метод. Создайте свойство, содержащее объект и соответствующий метод для инициализации его. Когда свойство читается, и его значение nil, вызовите связанный метод загрузки.

Выделение или загрузка данных, которые будут выведены на экран в представлении

viewDidLoad

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

Ответ на уведомления низкой памяти

didReceiveMemoryWarning

Используйте этот метод для освобождения всех некритических объектов, связанных с контроллером представления. На iOS 6 можно также использовать этот метод для выпуска ссылок для просмотра объектов.

Выпуск структур критических данных требуется Вашим контроллером представления

dealloc

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

На iOS 6 и Позже, Контроллер Представления Разгружает Свои Собственные Представления, Когда Желаемый

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

Если та дополнительная память необходима для приложения, можно явно выпустить иерархию представления. Перечисление 4-3 переопределяет didReceiveMemoryWarning метод для выполнения этого. Во-первых, вызовы реализация суперкласса для получения любого требуемого поведения по умолчанию. Затем это очищает ресурсы контроллера представления. Наконец, это тестирует, чтобы видеть, не является ли представление контроллера представления экранным. Если представление связано с окном, то оно очищает любую из сильных ссылок контроллера представления к представлению и его подпредставлениям. Если бы представления хранили данные, которые должны быть воссозданы, то реализация этого метода должна сохранить те данные прежде, чем выпустить любую из ссылок на те представления.

Перечисление 4-3  , Выпускающее представления контроллера представления, не видимого на экране

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Add code to clean up any of your own resources that are no longer necessary.
    if ([self.view window] == nil)
    {
        // Add code to preserve data stored in the views that might be
        // needed later.
 
        // Add code to clean up other strong references to the view in
        // the view hierarchy.
        self.view = nil;
    }

В следующий раз view к свойству получают доступ, представление перезагружается точно, поскольку это был первый раз.

Когда Память Является Низкой, на iOS 5 и Ранее, Система Может Разгрузить Представления

Когда память является низкой, в более ранних версиях iOS система автоматически пытается разгрузить представление представления контроллера. Шаги, происходящие во время разгрузить цикла, следующие:

  1. Приложение получает предупреждение низкой памяти от системы.

  2. Каждый контроллер представления вызывает didReceiveMemoryWarning метод. При переопределении этого метода Вы должны использовать его для выпуска любой памяти или возражаете, что объекту контроллера представления больше не нужно. Необходимо вызвать super в некоторый момент в Вашей реализации, чтобы гарантировать, что работает реализация по умолчанию. На iOS 5 и ранее, реализация по умолчанию пытается выпустить представление. На iOS 6 и позже, выходы реализации по умолчанию.

  3. Если представление не может быть безопасно выпущено (например, это видимо экранный), выходы реализации по умолчанию.

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

  5. Это устанавливает view свойство к nil.

  6. Контроллер представления вызывает viewDidUnload метод. Подкласс обычно переопределяет этот метод для выпуска любых сильных ссылок, которые это имеет к тем представлениям.

Рисунок 4-3 показывает визуальное представление разгрузить цикла для контроллера представления.

Рисунок 4-3  , Разгружающий представление из памяти