Re: Threads and Core Data, bindings results in view corruption
Re: Threads and Core Data, bindings results in view corruption
- Subject: Re: Threads and Core Data, bindings results in view corruption
- From: Ben Lachman <email@hidden>
- Date: Mon, 31 Mar 2008 16:05:19 -0400
On Mar 31, 2008, at 2:47 PM, Jeff LaMarche wrote:
On Mar 31, 2008, at 2:36 PM, David wrote:
On Mon, Mar 31, 2008 at 2:26 PM, Jeff LaMarche
<email@hidden> wrote:
4) You can, as Ben mentioned, use performSelector:onMainThread: to
actually have the object inserted on the main thread's context.
It's a bit of a pain, but threads are always at least a little
painful.
How? Core data says that to use NSManagedObjects between threads
you need to pass an ID and access it from another context. But you
don't even get an ID until you perform a save on the original
context. I'm then back to my original problem where the save
itself takes too long.
From what I've read so far, my current thinking is that I need to
give up on Core data. I can easily create my own objects, handle
my own locking or synchronization. I was thinking to still use
NSTreeController bound to my objects.
Its a shame because core data sounds so cool. I love the data
modeling aspects. Nice way to think through the problem even if I
end up not using it.
Well, I don't know exactly what you're doing in your thread, but
you could create a method that that took, for example, a dictionary
as an argument, then when you're ready to insert the object in your
thread, pass that method the values you need having it fire on the
main thread and then create the Core Data entity based on the
passed values and then insert it into the main thread's context.
If you needed to do further work on that entity, like adding
relationships to it, then it would get to be trickier, as you'd
also need to get its managedObjectID back to your thread.
Actually this isn't true. You can add relationships, etc. without
having to pass them around since you will be doing a save at some
point and that will sync everything back to the persistent store.
Then, once you pass the OID of your newly inserted object back to you
main thread you can fetch it from the store and the relationships you
added to it, etc. will be intact.
My worker thread looks something like this (pseudo-code):
Main thread:
[NSThread detachNewThreadSelector:@selector(workLoop:)
toTarget:newWorker withObject:self];
Worker thread executes work loop which inserts new managed objects,
saves them and sends the new oids back to the main thread by calling:
[owner performSelectorOnMainThread:@selector(addResults:) withObject:
[newManagedObjectSet valueForKey:@"objectID"] waitUntilDone:NO];
The worker also notifies its owner (which was passed to detach...)
just before exit.
This is loosely based on SIWorkerThread by Daniel Vollmer <http://
www.maven.de/2007/01/cocoa-worker-thread/> with use of
performSelectorOnMainThread to pass OIDs back.
You also should try using an SQLite store. It will be faster than a
binary store for saving incrementally since it only touches part(s)
of the file. However if you are adding lots of objects make sure you
look at how often you save and if there are ways to decrease that
frequency.
Lastly, I kind of wonder if there might be some way to integrate a
secondary In-Memory store into this setup for use in passing the
objects created by the worker thread back to the main thread, it
seems like it might introduce some more complexity but might also be
worthwhile performance-wise since saving to the SQL store does have a
certain amount of latency due to how it hits the disk (particularly
on Tiger). Any thoughts on this Ben?
->Ben
--
Ben Lachman
Acacia Tree Software
http://acaciatreesoftware.com
email@hidden
740.590.0009
_______________________________________________
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