当KVO从模型设置器触发时,防止以递归方式重新进入observeValueForKeypath

时间:2010-08-15 08:10:32

标签: objective-c cocoa models key-value-observing getter-setter

我有很多模特可以观察自己的变化。当触发一个setter时,模型中的观察者被调用,在该模型中,我调用Web服务器并更新Web服务器中的信息,以便它正确地拥有它应该的数据。

然而,在我对Web服务器的调用中,我可以收到任何错误,从连接被丢弃,服务器重置等到服务器,说不允许更新(例如,另一个用户更改的某些其他参数阻止了更新)。

哦,断开连接的数据存储的乐趣......

有没有办法在不重新触发KVO动作的情况下更新self(即模型)?

当我返回响应时,我可以关闭观察者,但是在执行后台服务器请求时,可以对同一对象执行另一个用户操作。这将打破另一个电话。

请参阅帖子here,了解我试图做的事情,以便首先进行观察,以及完整模型的代码示例。

我打电话的部分将在观察者中如下:

-(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 个答案:

答案 0 :(得分:2)

好吧,我最后采取了不同的策略。我没有依赖对象模型发布更新,而是将所有内容都提升到一个级别,让控制器处理更新。

基本上这个过程如下:

  1. 在需要时在模型中创建对象
  2. 在控制器中有一个setter,它在方法变量中保存对象设置的当前状态
  3. 将新设置传递到服务器,但只传递在现有设置和新设置之间更改的设置(所有增量值)
  4. 如果通过了呼叫,请更新模型,如果失败,则通知用户,不做任何其他操作
  5. 在每个控制器中都有更多的代码,但是通过动态地将当前值与新值进行比较,并且仅将已更改的值传递给服务器,我完成了相同的净结果。

    这允许我根据更改的数量传递一个或多个值,而无需通过一次又一次地调用公共服务器-API方法来硬编码setter和getter。

    实际效果是,我保留了所有KVC / KVO通知,而不必担心绕过它或不对某些电话进行KVC / KVO更新,而不是其他电话。