On Nov 18, 2011, at 15:21 , patrick machielse wrote:

> I need to _continuously_ merge changes made in the _main_ thread into a 
> context held by a background thread. Most (all?) discussions about 
> multi-threading in CoreData discuss merging changes from a _finite_ operation 
> in the _background_, a quite different situation.
> 
> Situation:
> ----------
> My application stores an object graph in CoreData using a persistent 
> document. The objects are manipulated by the user in the UI. Meanwhile a 
> background thread processes the object graph continuously to generate output.
> 
> Changes made by the user should be picked up and accounted for by the 
> background thread in a timely manner.
> 
> I've adopted 'thread confinement' as prescribed by Apple: the main thread and 
> the background thread eacht have separate contexts sharing a single 
> persistent store.
> 
> Options:
> --------
> There are two ways to receive updates on the background thread:
> 
> 1 - Through 'NSManagedObjectContextDidSaveNotification' and subsequent change 
> merging.
> 
> However, I'd have to save the document every time the user changes the 
> document. This would not be a good user experience, to say the least.
> 
> 2 - Through 'NSManagedObjectContextObjectsDidChangeNotification'
> 
> The objectIDs of the changed / inserted / deleted objects can be collected 
> from this notification and forwarded to the background thread. According to 
> Apple:
> 
>    "You pass the object IDs to thread A [-- my background thread --] by 
> sending a suitable message to an object on thread A. Upon receipt, on thread 
> A you can refetch the corresponding managed objects."
> 
> Here is where I miss information: The context of my background context isn't 
> aware of the changes in the main thread context (there was no merge) and 
> 'refetch the corresponding managed objects' won't work because the shared 
> persistent store wasn't updated (there was no save operation from the main 
> context)…

The MOCs are separate scratch pads. Core Data provides no connection between 
their object graphs except via save-dependent synchronization, therefore 
there's no Core Data solution to your problem. If you weren't using 
NSPersistentDocument, then using Core Data -[save:] would provide a possible 
solution, but NSDocument semantics of course prevent you from taking that 
approach.

> At the moment I cannot find an acceptable way to merge changes from the main 
> thread into the background thread context. Is there a solution for my use 
> case?

It's hard to suggest a solution when the description of your scenario is so 
general. (For example, I conclude that the main-thread operations are fairly 
lightweight, but the background-thread operations are fairly slow or intensive. 
Or not.)

I'd say it's worth taking some time to ask if Core Data is the correct 
technology to use for this. Do the conveniences and performance characteristics 
it provides outweigh the impedance mismatch with your application?

If you must use Core Data, it's worth taking some time to ask if this 
simplistic multi-threaded approach is the best approach. Is there a 
single-threaded solution that would work better? Is there a multi-threaded 
solution that uses a MOC in one thread only?

If you must use multiple MOCs in multiple threads, then the simplest solution 
may be to invent your own set of notifications (speaking generically, not 
implying NSNotification in particular) to send update-property dictionaries 
from the main thread to the background thread. (You could probably use a KVO 
observer on the main thread, send change-dictionaries to the background thread, 
and use KVC on the background thread to apply the changes, thus automating the 
process almost completely.) This may sound horrendous, but could perhaps be 
easier than it sounds.


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to