re: Core Data design question: receiving KVO notifications of partially mutated objects
re: Core Data design question: receiving KVO notifications of partially mutated objects
- Subject: re: Core Data design question: receiving KVO notifications of partially mutated objects
- From: Ben Trumbull <email@hidden>
- Date: Mon, 2 Nov 2009 12:58:45 -0800
> What is considered best practice when it comes to mutating many
> properties of a managed object, specifically with regard to KVO
> observers getting notified before all mutations are finished?
This is a problem intrinsic to the design of KVO. KVO is all about fine grained per property notifications. It's very well suited to that. However, it's common for complex objects to be in an intermediate state during a KVO notification.
There's no better notion of cross-property coherence than refactoring into a different property object that encapsulates everything.
> Let's say I have an Rectangle object. It has properties: colour, width,
> height. Imagine some controller observing all these properties, perhaps
> to trigger a redraw.
>
> If I do:
>
> [rect setColour:...];
> [rect setWidth:...];
> [rect setHeight:...];
In this example, the best KVO can do is work with a "colored rectangle" object that in turn is the 1 property you work with here. So, this would be an example of a granularity of notification that works better with NSNotificationCenter
> This is short and readable. But observers will be notified after each
> setter.
yup
> This could be a problem if intermediate states are not self-
> consistent and could also lead to unnecessary redrawing.
And many other performance issues if observers recalculate things too aggressively.
> In the general case, I might not even know who is observing.
Well, that's the point of the notification pattern.
>
> I guess it's safer to create a setColour:width:height: method in my
> NSManagedObject subclass that does:
>
> [self willAccessValueForKey:@"colour"];
> [self willAccessValueForKey:@"width"];
>
> [self setPrimitiveColour:...];
> [self setPrimitiveWidth:...];
>
> [self didAccessValueForKey:@"width"];
> [self didAccessValueForKey:@"colour"];
>
> Is this what I should be doing?
Generally, no. (setting aside, the calls should be to willChangeValueForKey:, btw)
If your issue is that drawing or recalculation is occurring too frequently after KVO changes, you can consider coalescing and deferring the observers' actions instead of performing them synchronously. This can be valuable even for less complex KVO issues.
You could also refactor the 3 properties into 1 object. Or use an NSNotification instead of KVO to adjust the granularity of notifications to better suit your drawing code.
This doesn't really have anything to do with Core Data. However, for NSManagedObject, Core Data already provides the change coalescing and NSNotifications for you. You can respond within NSManagedObjectContextObjectsDidChangeNotification instead.
- Ben
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden