- Like Reflection, Sort Of
- Keypaths
- Key Value Observing
- Dependent Keys
- Conclusion
Dependent Keys
Another very useful feature of the KVO/KVC protocols is the ability to assign dependent keys. As an example, imagine you have an object in a shopping cart application that represents a product to be purchased. In this object we have a quantity and an amount. The header for this example would be as follows:
#import <Cocoa/Cocoa.h> @interface ProductObject : NSObject { NSString *name; int quantity; double value; } - (NSString *)name; - (void)setName(NSString *); - (int)quantity; - (void)setQuantity:(int)q; - (double)value; - (void)setValue:(double)d; - (double)subtotal; - (double)taxes; @end
Normally we would also store the subtotal for the product as well as the calculated tax. Whenever the quantity is changed or the amount changes, both the subtotal and the tax need to be recalculated and reset. By defining a dependent key, we can eliminate this and let the protocol handle the dirty work for us.
To do this, we need to define the dependent keys in the initialize method as follows:
+ (void)initialize { NSArray *keys = [NSArray arrayWithObjects:@"quantity", @"value", nil]; [self setKeys:keys triggerChangeNotificationsForDependentKey:@"subtotal"]; [self setKeys:keys triggerChangeNotificationsForDependentKey:@"taxes"]; }
With the dependent keys set, every time a change is made to either the quantity or the amount, all observers will be notified that the dependent has been changed as well, causing a refresh. With this in place, the two "getter" methods now calculate methods that determine the values on the fly and do not bother to store them:
- (double)subtotal { return ([self value] * [self quantity]); } - (double)taxes { return ([self subtotal] * 0.065); }
Naturally, these are merely examples because taxes are generally much more complicated than a flat percentage. We could also make this slightly more complicated by making taxes a dependent key of subtotal instead of quantity and value.