Senseful
Senseful

Reputation: 91641

How to update an NSManagedObject whenever a specific attribute is changed?

Imagine I have a Core Data object, Product. Each Product has a quantity, price, and total attribute. Total is there for efficiency when retrieving items from the table. (I understand that there may be an efficient way to get the computed value using fetched properties, but this is only an example, and that answer is not what I am looking for.)

+------+----------+-------+-------+
| Name | Quantity | Price | Total |
+------+----------+-------+-------+
| Foo  |        1 |    20 |    20 |
| Bar  |        0 |    30 |     0 |
| Baz  |        3 |     5 |    15 |
+------+----------+-------+-------+

Assume that the price of a product never changes. However, the quantity does change. Whenever the quantity changes, I would like to be notified so that I can recompute the total. I would like to avoid using KVO if possible because I have a custom NSManagedObject class, product, and I would like to override one of its methods in order to update the price and not have to worry about registering/unregistering for notifications on its own attributes.

This method should only be called when the price is changed, not every time any of the attributes on the object has changed.

I would also like this method to be triggered right when the value is changed (e.g. not right before the context is saved), so that I can access the new total attribute before the context is saved.

Which method should I override and can it be done in a category on my Product class?


Note: this question is similar but is mainly concerned with running more than one thread, which may require more complicated answers. I am looking for something simple, on a single thread.

Upvotes: 1

Views: 627

Answers (1)

Martin R
Martin R

Reputation: 539685

You should override the setter method for the quantity attribute of your entity:

- (void)setQuantity:(NSNumber *)quantity
{
    [self willChangeValueForKey:@"quantity"];
    [self setPrimitiveValue:quantity forKey:@"quantity"];
    [self didChangeValueForKey:@"quantity"];

    NSNumber *price = ... // compute new price
    self.price = price;
}

You can add that code to a category of the Product class if you don't want to change the Xcode generated files.

Upvotes: 1

Related Questions