9

したがって、Invoice と InvoiceLineItem の 2 つのオブジェクトがあります。InvoiceLineItem には と呼ばれるプロパティがcostあり、他のプロパティに基づいて動的に作成されます。私が使用するKVO /バインディングを支援するには:

+ (NSSet *)keyPathsForValuesAffectingCost {
    return [NSSet setWithObjects:@"lineItemType", @"serviceCost", @"hourlyRate", @"timeInSeconds", @"productCost", @"quantityOfProduct", @"mileageCost", @"milesTraveled", nil];
}

これはうまくいきます。serivceCost のようなプロパティを編集すると、テーブル ビューのメイン コストが正常に更新されます。

Invoice オブジェクトには、InvoiceLineItems の NSMutableArray があります。Invoice には と呼ばれる同様のプロパティがありますtotalCost。これは、明細項目を繰り返し処理することによって計算され、明細項目が削除済みとしてマークされていない限り (同期の理由でこれを行っています)、コストを合計して totalCost を作成します。

今私の質問/問題。項目のコストの 1 つが変更されたときに KVO/バインディングで機能するように、Invoice の totalCost を設定するにはどうすればよいですか?

設定してみました:

+ (NSSet *)keyPathsForValuesAffectingTotalCost {
    return [NSSet setWithObjects:@"lineItems.cost", nil];
}

しかし、うまくいきません。コンソールに次のエラーが表示されます。[<NSCFArray 0x1499ff40> addObserver:forKeyPath:options:context:] is not supported. Key path: cost

4

2 に答える 2

6

自動 KVO 伝播で対多関係がサポートされているとは思えません。ドキュメンテーションは、どちらかというと明示的ではありませんが、私が KVO について一般的に知っていることから、対多関係のサブキーを観察することは自明ではありません。

これにアプローチする方法は、Invoice クラスのプロパティに to-many KVC アクセサーを実装して、それぞれ挿入/削除メソッドで addObserver/removeObserver 呼び出しをcost実行することにより、各 InvoiceLineItem オブジェクトのプロパティを手動で観察することです。 willChangeValueForKey:/didChangeValueForKey: を使用して手動で変更をlineItemsトリガーします。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"];
    }
}
于 2009-03-04T21:35:15.507 に答える
0

より短い解決策を試すことができます。

ヘッダー ファイルに追加します。

@property (retain, readonly) NSDecimalNumber *accountBalance;

実装ファイルに追加

- (NSDecimalNumber *)totalCost
{
    return [self valueForKeyPath:@"InvoiceLineItems.@sum.cost"];
}
于 2009-09-04T13:53:44.430 に答える