Когда использовать KVO? - программирование
Подтвердить что ты не робот

Когда использовать KVO?

Я прочитал много документов о KVO, но я все еще смущен тем, когда его использовать.

В случае, если objA хочет контролировать определенное свойство objB, например:

self.objB = [[ObjB alloc] init];
[self.objB addObserver:self
            forKeyPath:@"address"
               options:0
               context:nil];

поэтому если свойство objB изменяется, и его можно изменить только на self, почему бы просто не сделать это:

self.objB.property = @"newValue";
[self doSomethingBasedOnNewValueOfObjBnewProperty];

вместо

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context

{
    if(keyPath == @"address") {
        [self doSomethingBasedOnNewValueOfObjBnewProperty];
    }
}

Это может быть полезно при использовании с singleton, например self.objB = [ObjB sharedInstance], где свойства могут быть изменены другими объектами. Это единственный вариант использования?

4b9b3361

Ответ 1

Не все экземпляры всех классов создаются и редактируются только одним и тем же экземпляром (что фактически показывает ваш пример).

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

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

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

Ответ 2

Ответ Wain - совершенный. Я хотел бы внести свой вклад, указав некоторые примеры возможных применений KVO.

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

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

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


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

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