Circular dependencies in Cocoa bindings

It makes my head in ...

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

(There are several other fields that, in combination with A or B, produce data for several TextLabels)

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

So, I created two methods that make from A to B and B from A. And certain dependencies, for example:

+ (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 perform the conversion, and valueOfFieldA and valueOfFieldB are NSString that are bound to two text fields.

It works (but only one way, B is updated whenever A changes) if I delete the second if . When the second if defined, it just explodes because (I think) it sees that the update is updating and updating B, then because B is updating, it goes and updates A again, etc. Etc....

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

PS. I'm a Cocoa newbie, so please carry me around and don't hit too hard if this is a very trivial question ...

EDIT:

I probably need to clarify a few points:

calculatedFieldA takes the value B and returns A, as well as updates (via the setter method) valueOfFieldA . Similarly, calculatedFieldB takes the value A and returns B, also updates (via the setter method) valueOfFieldB .

This is on Lion with Xcode 4.1.

+4
source share
1 answer

Value transformers are almost certainly the right answer here. Do not store "A" and "B". Just save one of them. Value transformers are exactly the way to display and accept input for another.

+1
source

All Articles