key-value observer

Не подумайте ничего дурного. Просто при слове observer я вспоминаю лучшую стратегию всех времен Star Craft. Вы за кого играли или может быть играете? Я Зерга любил. А observer был у Протоссов. Ладно, перейдем к делу.

Что такое Key-Value Observing (KVO) в Objective-C?

Если мы заглянем на страницу официальной документации Apple, то обнаружим там следующее.

Key-value observing предоставляет механизм, который позволяет одним объектам быть оповещенными об изменении отдельных свойств других объектов. Это особенно применимо для коммуникации между моделью и контроллерами в приложении. В то же время модель может наблюдать за объектами другой модели или за другими объектами самой себя.

“Короче Склифософский!” Key-Value Observing?

Разберем KVO на простом примере. Предположим перед вами стоит задача прикрутить следующую фичу к приложению. Нужно добавить кнопку в виде смайлика, по нажатию на которую будет открываться NSPopover. Смайлик при этом должен менять вид. NSPopver закрывается при нажатии в любом месте экрана. Смайлик должен вернуться в первоначальное состояние.

key-value observing

Задача, в принципе, очень простая.

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

Вопрос в том, как вернуть смайлик в первоначальное состояние, когда NSPopover закроется?

И тут нам поможет  Key-Value Observing.

Если мы заглянем в класс NSPopver, то обнаружим в нем свойство shown, которое возвращает YES, когда NSPopover показывается, и NO – когда спрятан.

Для того, чтобы нам решить нашу задачу, нам нужно как-то следить за этим свойством shown и менять смайлик, когда оно изменяется. Это и делает KVO.

Первое, что нам надо сделать, добавить обсервер. Обычно это можно сделать в методах viewDidLoad или awakeFromNib

Мы только что добавили обсервер к нашему экземпляру класса NSPopover, который будет следить за изменениями свойства shown. В опциях мы указали отслеживать новое значение и старое.

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

– (void) observeValueForKeyPath: ofObject: change: context:

и является методом класса NSKeyValueObserving фреймворка Foundation.

Запустим наше приложение и нажмем на смайлик 1 раз для открытия диалога. Теперь нажмем в любом месте экрана для закрытия диалога. NSLog нам вывел следующее сообщение.

Как мы можем видеть нам пришел NSDictionary *change с ключами kind, new и old. И как мы можем видеть в первом случае новое значение shown стало 1, старое 0. Когда мы закрыли окно – shown изменился в первоначальное состояние.

Вот и все. Нам остается преобразовать значение ключей в BOOL (т.к. ключи содержат NSString* как можно видеть в описании метода) и вызвать метод, обновляющий состояние нашей кнопки.

В этом и есть Key-Value Observing.