所以我有两个对象,Invoice和InvoiceLineItem.InvoiceLineItem具有一个名为的属性cost
,它是基于其他属性动态创建的.为了帮助我使用KVO /绑定:
+ (NSSet *)keyPathsForValuesAffectingCost { return [NSSet setWithObjects:@"lineItemType", @"serviceCost", @"hourlyRate", @"timeInSeconds", @"productCost", @"quantityOfProduct", @"mileageCost", @"milesTraveled", nil]; }
这非常有效.当我编辑像serivceCost这样的属性时,表视图中的主要成本更新.
在Invoice对象中,我有一个InvoiceLineItems的NSMutableArray.发票有一个类似的属性叫做totalCost
.它是通过迭代订单项来计算的,只要订单项没有标记为已删除(我这样做是为了同步原因),就会增加成本并创建totalCost.
现在我的问题/问题.如何设置Invoice的totalCost,以便在其中一个订单项的费用发生变化时,它可以与KVO /绑定配合使用?
我尝试过设置:
+ (NSSet *)keyPathsForValuesAffectingTotalCost { return [NSSet setWithObjects:@"lineItems.cost", nil]; }
但它不起作用.我最终在控制台中出错:[
我不相信自动KVO传播支持许多关系.文档并没有明确说明这种方式,但从我对KVO的一般知识来看,观察多对多关系的子键往往是不平凡的.
我接近这个的方法是手动观察cost
每个InvoiceLineItem对象的lineItems
属性,方法是分别在插入/删除方法中对Invoice类执行addObserver/removeObserver调用的属性的to-many KVC访问器,然后totalCost
使用willChangeValueForKey:/ didChangeValueForKey:手动触发更改:所以这样的事情(粗略的草图代码,免责声明等):
- (void)insertObject:(InvoiceLineItem*)newItem inLineItemsAtIndex:(unsigned)index { [newItem addObserver:newItem forKeyPath:@"cost" options:0 context:kLineItemContext]; [lineItems insertObject:newItem atIndex:index]; } - (void)removeObjectFromLineItemsAtIndex:(unsigned)index { [[lineItems objectAtIndex:index] removeObserver:self forKeyPath:@"cost"]; [lineItems removeObjectAtIndex:index]; } - (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context { if (context == kLineItemContext) { [self willChangeValueForKey:@"totalCost"]; [self didChangeValueForKey:@"totalCost"]; } }