David, Jeff, Ben

There are a few issues here.

First, enough pieces of AppKit and Cocoa Bindings are not thread safe that, even without Core Data, you just can't do this in this particular fashion.

If you want multi-threaded work with the view and controller classes in Cocoa, you'll need to perform your background operations, and communicate back to the main thread (view & controllers) via the run loop. -performSelectorOnMainThread and its friends in NSThread.h are your best bet.

Using a run loop on a background thread and communicating from the main thread to it with the new 10.5 -performSelector... methods is often conceptually simpler (easier to debug) than many other threading patterns.

Sharing a MOC with Cocoa Bindings and a background thread will end in tears. Cocoa Bindings doesn't lock its bound MOC, so you're basically SOL.

Even if it did work, though, it'd be a bad idea. Sharing a MOC means a background thread would still at times block the main thread and SPOB your app.

These 3 points (can't work, doesn't work, shouldn't work) are why the Core Data Programming Guide says don't do this.

This isn't to say what what you intend to accomplish is wrong or undesirable. Quite the contrary. Just that this 'how' is going in the wrong direction.

The Core data programming guide says its best to maintain a separate
managedObjectContext per thread. But this appears to require the data to be
written to persistent store to make it work (file). That not reasonable in
my case where I'm adding many objects to an object tree. It takes a
significant amount to time to write it out, negating the benefit of trying
to make the UI seem responsive.

The list archives also have these, which you should read:
<http://lists.apple.com/archives/cocoa-dev/2007/May/msg00222.html>
<http://lists.apple.com/archives/cocoa-dev/2008/Jan/msg01889.html>

It's possible to shuttle pending changes between threads by hand using KVC.

On Tiger, saves are especially expensive as the default behavior was to use a more correct/aggressive version of fsync, specifically fcntl(...,F_FULLFSYNC). This is 100-1000x slower than fsync, which technically is incorrect on nearly all consumer grade hard drives at a hardware level.

On Leopard, we made significant performance optimizations, so the user experience can vary greatly between the two OS's.

If you're inserting a large number of new objects, you really should just batch the operation together, save, and present the user with new objects in the tree view in batches.

On Leopard, in the scenarios under which you can save, you can also use -mergeChangesFromContextDidSaveNotification:

While AppKit & Bindings makes it impossible to share a MOC with a background thread, theoretically all your background threads can share a MOC if you lock and unlock them. Or you could just have 1 background thread processing asynchronous operations. That'd be a lot easier to debug.

You should also use the Debug libraries and Core Data multi-threaded assertions:
<http://lists.apple.com/archives/cocoa-dev/2008/Mar/msg01098.html>

Life's a lot easier when your app halts in gdb as soon as you make a mistake. 'thread apply all bt' is your friend.

Finally, in 4 years no one has filed a bug about this.

If one developer has a problem, it's unfortunate. If three developers have a problem, it's an issue. If two hundred developers have a problem, it's a crisis.

Kinda hard to tell the difference if developers can't be bothered to speak up in the only way that really matters: bugerport.apple.com

Feature requests, performance problems, and enhancement suggestions are all "bugs"
--

-Ben
_______________________________________________

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 [EMAIL PROTECTED]

Reply via email to