Регистрация для наблюдения значения ключа

Для получения уведомлений наблюдения значения ключа для свойства три вещи требуются:

Регистрация как наблюдатель

Чтобы быть уведомленным относительно изменений в свойстве, объект наблюдения должен сначала зарегистрироваться в объекте, который будет наблюдаться путем отправки его addObserver:forKeyPath:options:context: сообщение, передавая объект наблюдателя и ключевой путь свойства, которое будет наблюдаться. Параметр опций указывает информацию, предоставленную наблюдателю, когда отправляется уведомление изменения. Используя опцию NSKeyValueObservingOptionOld указывает, что значение исходного объекта предоставлено для наблюдателя как запись в словаре изменения. Указание NSKeyValueObservingOptionNew опция обеспечивает новое значение как запись в словаре изменения. Для получения обоих значений Вы были бы поразрядно OR константы опции.

Пример в Перечислении 1 демонстрирует регистрацию объекта инспектора для свойства openingBalance.

Перечисление 1  , Регистрирующее инспектора как наблюдатель openingBalance свойства

- (void)registerAsObserver {
    /*
     Register 'inspector' to receive change notifications for the "openingBalance" property of
     the 'account' object and specify that both the old and new values of "openingBalance"
     should be provided in the observe… method.
     */
    [account addObserver:inspector
             forKeyPath:@"openingBalance"
                 options:(NSKeyValueObservingOptionNew |
                            NSKeyValueObservingOptionOld)
                    context:NULL];
}

При регистрации объекта как наблюдатель можно также обеспечить указатель контекста. Указатель контекста предоставлен для наблюдателя когда observeValueForKeyPath:ofObject:change:context: вызывается. Указатель контекста может быть указателем C или ссылкой на объект. Указатель контекста может использоваться в качестве уникального идентификатора для определения изменения, наблюдающегося, или предоставлять некоторые другие данные наблюдателю.

Получение уведомления об изменении

Когда значение наблюдаемого свойства объекта изменяется, наблюдатель получает observeValueForKeyPath:ofObject:change:context: сообщение. Все наблюдатели должны реализовать этот метод.

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

Словарная статья изменения NSKeyValueChangeKindKey предоставляет информацию о типе произошедшего изменения. Если значение наблюдаемого объекта изменилось, NSKeyValueChangeKindKey возвраты записи NSKeyValueChangeSetting. В зависимости от опций, указанных, когда наблюдатель был зарегистрирован, NSKeyValueChangeOldKey и NSKeyValueChangeNewKey записи в словаре изменения содержат значения свойства прежде, и после, изменение. Если свойство является объектом, значение предоставлено непосредственно. Если свойство является скаляром или структурой C, значение обертывается в NSValue объект (как с кодированием значения ключа).

Если наблюдаемое свойство к - многие отношение, NSKeyValueChangeKindKey запись также указывает, были ли объекты в отношении вставлены, удалены или заменены путем возврата NSKeyValueChangeInsertion, NSKeyValueChangeRemoval, или NSKeyValueChangeReplacement, соответственно.

Словарная статья изменения для NSKeyValueChangeIndexesKey NSIndexSet объект, указывающий индексы в изменившемся отношении. Если NSKeyValueObservingOptionNew или NSKeyValueObservingOptionOld когда наблюдатель регистрируется, указаны как опции NSKeyValueChangeOldKey и NSKeyValueChangeNewKey записи в словаре изменения являются массивами, содержащими значения связанных объектов прежде, и после, изменение.

Пример в Перечислении 2 показывает observeValueForKeyPath:ofObject:change:context: реализация для инспектора, отражающего старые и новые значения свойства openingBalance, как зарегистрировано в Перечислении 1.

  Реализация перечисления 2 observeValueForKeyPath:ofObject:change:context:

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context {
 
    if ([keyPath isEqual:@"openingBalance"]) {
        [openingBalanceInspectorField setObjectValue:
            [change objectForKey:NSKeyValueChangeNewKey]];
    }
    /*
     Be sure to call the superclass's implementation *if it implements it*.
     NSObject does not implement the method.
     */
    [super observeValueForKeyPath:keyPath
                         ofObject:object
                           change:change
                           context:context];
}

Удаление объекта как наблюдатель

Вы удаляете наблюдателя значения ключа путем отправки наблюдаемого объекта a removeObserver:forKeyPath: сообщение, указывая наблюдение возражает и ключевой путь. Пример в Перечислении 3 удаляет инспектора как наблюдателя openingBalance.

Перечисление 3  , Удаляющее инспектора как наблюдатель openingBalance

- (void)unregisterForChangeNotification {
    [observedObject removeObserver:inspector forKeyPath:@"openingBalance"];
}

Если контекст является объектом, необходимо сохранить сильную ссылку к нему до удаления наблюдателя. После получения a removeObserver:forKeyPath: сообщение, объект наблюдения больше не будет принимать никого observeValueForKeyPath:ofObject:change:context: сообщения для указанного ключевого пути и объекта.