• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Bindings vs MOC change notification
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bindings vs MOC change notification


  • Subject: Re: Bindings vs MOC change notification
  • From: "email@hidden" <email@hidden>
  • Date: Sat, 14 Nov 2009 10:59:36 +0000

On 14 Nov 2009, at 02:11, David Catmull wrote:

> In my Core Data app, I have objects with a date property, and I want to maintain a list of all years that I have objects in. I'm having trouble settling on an approach.
>
> Currently, I'm listening for NSManagedObjectContextObjectsDidChangeNotification. This is working fine for additions and deletions, but it's harder for changes, mainly because I don't know the old value. If I did, I could check if the old year still has any other objects in it. As it is I have to refresh the whole list. I also get more notifications than I need, since I only care about date changes on this one entity.
You could cache the old year in a transient property and detect the change that way.

>
> Another option is to use KVO so I can be notified only of date changes. I'm assuming that registering as an observer for potentially thousands of Core Data objects doesn't carry too much overhead. The down side is that if lots of objects change at once, I get lots of individual callbacks, and I worry that that would be a bottleneck.
>
I find it hard to get a combination of KVO, bindings, CoreData and undo that works cleanly and efficiently.
I faced a perhaps similar situation and implemented a system of coalescing notifications.

My NSManagedObject subclass raises manual KVO notifications for use in bindings put each property modified also calls subclass method -postPropertyChangeNotification: (see below).
This sends a single notification for each modified keypath at the end of the runloop.
This means you get one notification regardless of how many changes there are.
So regardless of how many objects get their Year property modified you get one notification and can form your year list.

Another subclass method +keyPathsThatDoNotEnqueueCoalescingNotifications provides a way of overriding the coalescing for individual keypaths.

One point would be to consider if you want to support undo.
CoreData will undo your changes to your data model and post KVO notes but it won't access your model accessor's during undo.
Its possible to build a series of observations and notifications that works when doing, but fails when undoing.
So if you want undo support I would try to implement it now.

To get undo support to function so that the GUI was always in sync with the model i found it necessary to listen for NSManagedObjectContextObjectsDidChangeNotification as well.

/*

 post property change notification

 provides an alternative to observing all model properties

 */
- (void)postPropertyChangeNotification:(NSString *)keyPath
{
	// build our notification
	NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:keyPath, @"keyPath", nil];
	NSNotification *notification = [NSNotification notificationWithName:@"MGSUnitEntryUpdated" object:self userInfo:userInfo];

	// the default is that we shall coalesce these notifications
	NSUInteger coalesceMask = NSNotificationCoalescingOnName;

	// determine any keyPaths that require distinct notifications
	// eg: date as the receiver of the notification treats it differently to all other keypaths
	NSSet *nonCoalescingKeypaths = [[self class] keyPathsThatDoNotEnqueueCoalescingNotifications];
	if ([nonCoalescingKeypaths containsObject:keyPath]) {
		coalesceMask = NSNotificationNoCoalescing;
	}

	// enqueue the notification
	[[NSNotificationQueue defaultQueue] enqueueNotification:notification
										postingStyle:NSPostASAP		// run at end of runloop
										coalesceMask:coalesceMask
										forModes:nil];
}

/*

 keypaths that do not enqueue coalescing notifications

 */
+ (NSSet *)keyPathsThatDoNotEnqueueCoalescingNotifications
{
	NSSet *keyPaths = [super keyPathsThatDoNotEnqueueCoalescingNotifications];

	// we require that separate uncoalesced notifications are sent for these property changes
    keyPaths = [keyPaths setByAddingObjectsFromSet: [NSSet setWithObjects: @"date", nil]];

    return keyPaths;
}


> Recommendations? Other options?
>
> Thanks,
>
> --
> David Catmull
> email@hidden
> http://www.uncommonplace.com/
>
> _______________________________________________
>
> 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

_______________________________________________

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

References: 
 >Bindings vs MOC change notification (From: David Catmull <email@hidden>)

  • Prev by Date: Re: Stack-based C++ class to wrap NSAutoreleasePool
  • Next by Date: Re: CPU sampling and +[NSURLConnection(NSURLConnectionReallyInternal) _resourceLoadLoop:]
  • Previous by thread: Re: Bindings vs MOC change notification
  • Next by thread: Core Data: Begin+End Undo Group = Dirty Dot. Why?
  • Index(es):
    • Date
    • Thread