Maybe rather than observing potentially many key value paths, why not have each object in the array post a notification when something has changed, then only one object needs to observe one notification instead of one object observing many key value paths.
EDIT:
Also, your arrayed objects could also respond to a class method called +keyPathsForValuesAffecting<key>
where <key>
is your key name. Here's an example: paymentDue
is a key, which is affected when the values invoiceItems.count
or paymentsMade
have changed. When invoiceItems.count
or paymentsMade
has changed, anything bound to paymentDue
is sent a notification.
+ (NSSet *) keyPathsForValuesAffectingPaymentDue:
{
return [NSSet setWithObjects:@"invoiceItems.count", @"paymentMade", nil];
}
If you are running on 10.4, or are targeting 10.4 or earlier, you'll need to use this method instead, but it essentially boils down to the same thing.
EDIT 2:
To clarify your other comment; you can still have each object in the array manually call
[[NSNotificationCenter defaultCenter] postNotificationName:@"ModelDidChange" object:self];
Then, with some controller code you can register for notification updates from your objects. If you choose a unique notification name then you won't need to manually listen from specific objects, you can tell the NSNotificationCenter
that you want to receive notifications from any object. Your controller can work out which object has changed quite easily.
Register with the notification center (these methods should be in a controller object):
// This string could really be just about anything you want, but make it conspicuous.
static NSString * const ModelDidChangeName = @"ModelDidChange";
- (void) awakeFromNib
{
// using nil for the object parameter will make the notification center
// invoke modelDidChange: regardless of who the sender is.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(modelDidChange:) name:ModelDidChangeName object:nil];
}
Implement a method to handle the notification.
- (void) modelDidChange:(NSNotification *) notification
{
MyModelClass *myObject = [notification object];
// do stuff with your model if necessary.
// do stuff with your view too
}
Get your model objects to post notifications when parts of them change:
@implementation MyModelClass
- (void) setSomething:(NSString *) newThing
{
[something autorelease];
something = [newThing copy];
if (something == nil)
{
// special case scenario for when something is nil
// do stuff, modify MyModelClass instance's attributes
[[NSNotificationCenter defaultCenter] postNotificationName:ModelDidChange object:self];
// the controller's modelDidChange: method is automatically invoked.
}
}
@end
But
If your model is properly KVC compliant and made with the appropriate KVO callbacks, manual notifications won't be necessary.