Frage

Also ich habe zwei Objekte, Rechnung und InvoiceLineItem. InvoiceLineItem hat eine Eigenschaft namens cost und dynamisch auf andere Eigenschaften basierend erstellt. Um mit der KVO / Bindungen Ich benutze:

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

Dies funktioniert gut. Wenn ich eine Eigenschaft wie serivceCost die Hauptkosten in der Tabellenansicht bearbeiten aktualisiert Ordnung.

Im Rechnungs Objekt habe ich eine NSMutableArray von InvoiceLineItems. Rechnung hat eine ähnliche Eigenschaft namens totalCost. Es wird durch Iterieren über die Positionen berechnet und solange die Position nicht als gelöscht markiert ist (was ich für die Synchronisierung Gründen tun) es die Kosten addiert und schafft die Totalcost.

Nun meine Frage / Problem. Wie kann ich so Rechnung des Totalcost auf, dass es mit KVO / Bindungen funktioniert, wenn eine der Kosten der Position geändert?

Ich habe versucht, die Einrichtung:

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

, aber es funktioniert nicht. Ich am Ende mit einem Fehler in der Konsole: [<NSCFArray 0x1499ff40> addObserver:forKeyPath:options:context:] is not supported. Key path: cost

War es hilfreich?

Lösung

Ich glaube nicht, zu viele Beziehungen zum automatischen propogation KVO unterstützt werden. Die Dokumentation sagt nicht ausdrücklich eine oder andere Weise, aber von dem, was ich weiß, von KVO im Allgemeinen beobachtete Subkeys eines n-Beziehung neigt nicht-trivial zu sein.

So wie ich dies manuell wäre nähern würde, um die cost Eigenschaft jedes InvoiceLineItem Objekt zu beobachten, indem Sie die zu viele KVC Accessoren für die lineItems Eigenschaft auf der Rechnungsklasse Implementierung eines addObserver / removeObserver Anruf im Einsatz zu tun / entfernen Methoden sind, und dann die Änderung totalCost manuell auslösen willChangeValueForKey Verwendung: / didChangeValueForKey :. So etwas wie dieser (skizzenhafte Code, Haftungsausschluss etc.):

- (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"];
    }
}

Andere Tipps

Sie können eine kürzere Lösung versuchen.

In

zu der Header-Datei:

@property (retain, readonly) NSDecimalNumber *accountBalance;
In

zur Umsetzung Datei

- (NSDecimalNumber *)totalCost
{
    return [self valueForKeyPath:@"InvoiceLineItems.@sum.cost"];
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top