所以我有两个对象,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];
}
但它不起作用。我最终在控制台中出现错误:[<NSCFArray 0x1499ff40> addObserver:forKeyPath:options:context:] is not supported. Key path: cost
答案 0 :(得分:6)
我不相信自动KVO传播支持许多关系。文档并没有明确说明这种方式,但从我对KVO的一般知识来看,观察多对多关系的子键往往是非平凡的。
我接近这个的方法是手动观察每个InvoiceLineItem对象的cost
属性,方法是在Invoice类上为执行addObserver /实现lineItems
属性的to-many KVC访问器removeObserver分别在insert / remove方法中调用,然后使用willChangeValueForKey:/ didChangeValueForKey:手动触发totalCost
更改。所以这样的事情(大致草拟的代码,免责声明等):
- (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"];
}
}
答案 1 :(得分:0)
您可以尝试更短的解决方案。
添加到头文件:
@property (retain, readonly) NSDecimalNumber *accountBalance;
添加到实施文件
- (NSDecimalNumber *)totalCost
{
return [self valueForKeyPath:@"InvoiceLineItems.@sum.cost"];
}