4

This is doing my head in...

Simplified version: I have two text fields - Field A and Field B. Field B can be derived from field A and similarly Field B can be derived from Field A.

(There's couple of other fields that in combination with either A or B produce data for multiple TextLabels)

What I want to do is: when user changes Field A, Field B is updated, and vice versa.

So I created two methods that do A to B and B to A. And defined dependencies like:

+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key
{
  NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key];


  if ([key isEqualToString:@"calculatedFieldA"]) {
      NSSet *dependentKeys = [NSSet setWithObjects:@"valueOfFieldB", nil];
      keyPaths = [keyPaths setByAddingObjectsFromSet:dependentKeys];        
  }

  if ([key isEqualToString:@"calculatedFieldB"]) {
      NSSet *dependentKeys = [NSSet setWithObjects:@"valueOfFieldA", nil];
      keyPaths = [keyPaths setByAddingObjectsFromSet:dependentKeys];        
  }

  return keyPaths;
}

Where calculatedFieldA and calculatedFieldB are the methods that do the conversion and valueOfFieldA and valueOfFieldB are NSString's that are bound to the two text fields.

It works (but only one way, B is updated whenever A changes) if I remove the second if statement. When the second if is defined, it just bombs out, because (I think) it sees A updated so goes and updates B, then because B is updated, goes and updates A again, etc, etc...

What is the best way to achieve this circular dependency? Is it a time to start reading about ValueTransformers?

PS. I'm a Cocoa newbie so please bear with me and don't punch too hard if this is a very trivial question...

EDIT:

I probably need to clarify few points:

calculatedFieldA accepts B value and returns A, also updates (via setter method) valueOfFieldA. Similarly calculatedFieldB accepts A value and returns B, also updates (via setter method) valueOfFieldB.

This is on Lion, with Xcode 4.1.

rytis
  • 2,649
  • 22
  • 27

1 Answers1

1

Value transformers are almost certainly the correct answer here. Don't store "A" and "B". Just store one of them. Value transformers are exactly the way to display and accept input for the other one.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610