On Jul 31, 2010, at 12:03, Chris Tracewell wrote:
> I have two arrays, A and B, that each contain objects that have a myTotal
> property. In IB I use an array controller for each and show their contents in
> separate NSTableview's and then display the sum for each by binding to
> respective NSTextField's using the @sum array operator on their
> arrangedObjects property.
You have the terminology slightly wrong. You're binding *from* the UI element
(NSTextField), not *to* it.
> Now I want to bind the difference between array A and array B but am having
> problems. In my model where the arrays reside, I added a readonly property
> for myDifference. I implemented the method for -(NSDecimalNumber
> *)myDifference like so...
>
> -(NSDecimalNumber *) myDifference
> {
> NSDecimalNumber *theTotalArrayA = [self
> valueForKeyPath:@"[email protected]"];
> NSDecimalNumber *theTotalArrayB = [self
> valueForKeyPath:@"[email protected]"];
> return [theTotalArrayA decimalNumberBySubtracting: theTotalArrayB];
> }
>
> This works when the view is first loaded but does not change myDifference
> when the user changes A or B total in the UI. To get myDifference to adjust I
> implementing in the model...
>
> +(NSArray*)keyPathsForValuesAffectingMyDifference
> {
> return [NSArray arrayWithObjects: @"myArrayA",@"myArrayB",nil];
> }
>
> This works if I add or remove items to the arrays but does not change
> myDifference if myTotal is changed for any of the objects in either of the
> arrays. How do I achieve this? Should I manually observe change in the
> controller using controlTextDidEndEditing delegate for the TableView's and
> then send a setMyDifference message to the model object?
No, absolutely not! :) This would push part of your data model behavior out
into the user interface, and that's a Bad Thing™. (Actually, you already did
that by doing a @sum calculation in both your data model and your UI, which is
not a great idea either.)
> Or am I missing a more elegant solution?
There are two ways of solving this. Assuming that M is your data model object
that contains the array properties A and B, ...
1. You can have M KVO-observe the 'myTotal' property of *all* of the objects in
the A and B arrays.
This approach is a bit of a PITA, because manually adding observers, while not
difficult, involves a bit of housekeeping.
2. You can have the 'myTotal' property manually generate a KVO notification for
M's 'myDifference' property when an individual total changes.
The drawback with this approach is that the objects in the arrays need to know
what the model object is. If that's unacceptable, you'll have to use solution
#1.
Actually, I'd think I'd create 'myAArrayTotal' and 'myBArrayTotal' properties
in M, arrange for changes to 'myTotal' to generate a notification for either of
those, then make 'myDifference' dependent on both of those *and* bind the UI
elements to the various properties of M directly. (That also solves the problem
of having both the UI and the model needing to know the correct way to
calculate the sums.)
In order for this to work, the objects in the arrays must be KVO-compliant for
their 'myTotal' property, although that was already a requirement for your
original solution to work correctly as far as it went.
_______________________________________________
Cocoa-dev mailing list ([email protected])
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com
This email sent to [email protected]