Le 19 nov. 2011 à 00:21, patrick machielse a écrit :

> I'm struggling a bit with multi-threading approaches for CoreData…
> 
> 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)...
> 
> 
> 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?
> 
> I could probably try to extend a solution with locking, but it will be error 
> prone…

If you can limit yourself to 10.7 have you look at the changes of 
NSManagedObjectContext. You can now have parent-child relationship between 
contexts. A save: on a child context will propagate to the parent context, not 
to the persistent store. And a fetch: on a child context is done through the 
context to the parent context (if I understand correctly).

I did some tests with a parent context for UI inited with 
NSMainQueueConcurrencyType and a child context inited with 
NSPrivateQueueConcurrencyType. The changes in the child context are 
automatically reflect in the UI after a save: on the child context.

Look at the release notes for Core Data for Lion.

-- 
Frédéric


_______________________________________________

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