Предотвращение повторного входа в наблюдаемое значение для рекурсивного ключа при срабатывании КВО из установщика модели - PullRequest
2 голосов
/ 15 августа 2010

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

Тем не менее, при моем обращении к веб-серверу я могу получить сообщение об ошибке для чего-либо от разрыва соединения, сброса сервера и т. Д. До сервера, говорящего, что обновление не разрешено (например, какой-то другой параметр, измененный другим пользователем, предотвратил обновление ).

О, радости отключенного хранилища данных ...

Можно ли каким-либо образом обновить self (т.е. модель) без повторного запуска действия KVO?

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

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

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

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

  if ([keyPath isEqual:@"firstName"]) {

    if !([serverCall value:[change objectForKey:NSKeyValueChangeNewKey] 
                    forKey:@"firstName"]) {

        // Notify the user of the problem and somehow do a 
        // [self setFirstName:[change objectForKey:NSKeyValueChangeOldKey]]
        // without firing off a KVO which would only loop this process
    }
  }

  if ([keyPath isEqual:@"lastName"]) {
    // Do whatever I need to do
  }
}

Вы, ребята, всегда, кажется, даете хороший совет, и я всегда благодарен за любые ваши предложения.

1 Ответ

2 голосов
/ 23 сентября 2010

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

По сути, процесс был следующим:

  1. Созданиеобъекты в модели при необходимости
  2. Наличие в контроллере установщика, который содержал в переменной метода текущее состояние параметров объекта
  3. Передал новые параметры на сервер, но только те, которыеизменение между существующими и новыми настройками (все значения дельты)
  4. Если вызов пройден, обновите модель или, если произошел сбой, уведомите пользователя и больше ничего не делайте

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

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

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

...