Получение 2 уведомлений KVO за одно изменение KVC - PullRequest
17 голосов
/ 15 декабря 2010

Я использую KVC / KVO для создания пользовательской реализации привязок для университетского проекта (она должна быть индивидуальной, поскольку я хочу делать что-то помимо того, что могут делать привязки, в том числе запускаться на iOS).

У меня есть «контроллер привязок», который регистрирует уведомления KVO по ряду ключей на объекте (используя addObserver: forKeyPath: options: context :), и я получаю уведомления. Однако я получаю два уведомления для каждого изменения. У меня есть идея для обхода проблемы, но я бы предпочел почему это происходит и исправить это!

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

Спасибо.

Edit:

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

Это одно из свойств, которые я наблюдаю (я знаю, что это немного странно, но этот класс по существу представляет некоторые свойства NSManagedObject как свойства самого себя):

- (void)setName:(NSString *)name
{
    [self willChangeValueForKey:@"name"];
    [contact setFirstName:name];
    [self didChangeValueForKey:@"name"];
}

Это код, который я использую для наблюдения за этим свойством (подтверждено, что оно запускается только один раз и только в одном месте):

[viewModel addObserver:self
            forKeyPath:@"name"
               options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial)
               context:viewController];

Любые вызовы после этого, которые изменяют это свойство, например ::1010.

viewModel.name = @"Joe";
[viewModel setName: @"Joe"];
[viewModel setValue: @"Joe" forKey: @"name"];

вызовет метод:

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

вызывается дважды, каждый раз с одинаковыми аргументами.

Ответы [ 2 ]

22 голосов
/ 15 декабря 2010

Вы делаете это:

- (void)setName:(NSString *)name
{
    [self willChangeValueForKey:@"name"];
    [contact setFirstName:name];
    [self didChangeValueForKey:@"name"];
}

Но (по звукам) из не-NSManagedObject подкласса. Это означает, что Cocoa будет пытаться автоматически отправлять вам уведомления KVO. Вы дополняете это, отправляя свои собственные тоже. Решения:

  • Переопределить +automaticallyNotifiesObserversForKey: для возврата NO
  • Измените свой метод на:

    - (void)setName:(NSString *)name { [contact setFirstName:name]; }

1 голос
/ 15 декабря 2010

Возможно, добавьте NSLog в ваш addObserver вызов, чтобы увидеть, добавляете ли вы двух наблюдателей.

...