質問

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

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

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

Invoiceオブジェクトには、InvoiceLineItemsのNSMutableArrayがあります。請求書には、totalCostという同様のプロパティがあります。これは、広告申込情報を反復処理することで計算され、広告申込情報が削除済みとしてマークされていない限り(同期の理由で)、コストが加算され、totalCostが作成されます。

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

設定しようとしました:

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

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

役に立ちましたか?

解決

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

これにアプローチする方法は、各InvoiceLineItemオブジェクトの cost プロパティを手動で観察することです。これには、 lineItems プロパティのそれぞれinsert / removeメソッドでaddObserver / removeObserver呼び出しを行う請求書クラスは、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"];
    }
}

他のヒント

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

ヘッダーファイルに追加:

@property (retain, readonly) NSDecimalNumber *accountBalance;

実装ファイルに追加

- (NSDecimalNumber *)totalCost
{
    return [self valueForKeyPath:@"InvoiceLineItems.@sum.cost"];
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top