Question

I have a whole host of models that watch themselves for changes. When a setter is triggered, the observer in the model is called and within that model I make a call to a web server and update information in the web server so it correctly has the data it should.

However, in my call to the web server I can get back an error for anything from connection being dropped, server reset etc to the server saying the update wasn't allowed (e.g. some other parameter changed by another user prevented the update).

Oh the joys of a disconnected data store...

Is there any way that I can update self (i.e. the model) without it re-triggering a KVO action?

I could turn off the observer when I get back the response, but another user action to the same object is possible while the background server request is being performed. This would then break the other call.

See the post here for an explanation of what I was trying to do to get the observation happening in the first place and a code example of the full model.

The portion where I am making the call would be in the observer as follows:

-(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
  }
}

You guys always seem to come through on some good advice and I am always grateful for any suggestions you may have.

Was it helpful?

Solution

Well I ended up taking a different tack. Instead of relying on the object model to post the updates, I took everything up one level and let the controller handle the updates.

Essentially the process was as follows:

  1. Create the objects in the model when required
  2. Have a setter in the controller that held in a method variable the current state of the object settings
  3. Passed the new settings up to the server, but only those that changed between the existing and the new settings (all the delta values)
  4. If the call passed, update the model or, if it failed, notify the user and do nothing more

It worked out being a little more code in each controller, but by dynamically comparing the current values with the new values and only passing up the ones that had changed to the server I accomplished the same net result.

This allows me to pass up one of more values based upon how many changed without having to hard-code setters and getters with a call to a common server-API method over and over again.

The net effect was that I keep all my KVC/KVO notification without worrying about bypassing it or not doing KVC/KVO updates on some calls and not on others.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top