At 1:49 PM -0400 3/31/08, David wrote:
I'm relatively new to Cocoa.

Welcome.

From my previous work in win32 and Java this is the normal scenario, not an unusual one. Can someone point me to some sample code that illustrates how to have a worker thread updating data which is displayed in the UI?

There's a Background Fetching example in /Developer/Examples/CoreData/

You can file bugs against the doc, and Core Data, and for a better example. File early, file often.

In the meantime, the list is a great place to ask questions.

In my case I am/was trying to maintain a outline view representing files, storing each node in core data. Based on these responses I'm not sure what technologies I should reasonably be using. Is this too fine grained for Core Data? Should I give up on bindings? Should I give up on NSTreeController?

If you're on 10.5, I definitely would not give up on Bindings and the tree controller. It's my understanding there are issues with the tree controller on 10.4. Bindings is a bit outside my area of expertise, so I recommend googling about the tree controller on 10.4. I vaguely recall Jonathan writing up something about this on <http://rentzsch.com/>

As for Core Data, I recommend you change your store to SQLite (1 line) and see where that puts you.

If you're still having trouble with this, and you should really file a bug report, and attach a Shark sample, and we'll see if we can identify some improvements for you to use.

One reason to file bugs is, occasionally, you'll get a nice work arounds back from Apple Developer Relations and continue on your merry way.

In contrast, some developers have needlessly tormented themselves, say trying to use GC, without asking any questions on the list or filing bugs for many months.

If I try to maintain multiple MOCs, that means I have to save to get it to show up in the other moc, right?

Yes.  I'd ask the controller via -performSelectorOnMainThread:

The save as binary file can take 15 seconds in my case when I have thousands of nodes.

That's bad. Use an sqlite store instead. First, even without threads, it'll handle thousands of nodes MUCH better. Faster, smaller, goodness all around.

Secondly, with multiple threads you can get up to 29,000 inserts per second going.

That hangs the UI longer than adding the nodes to start with. Should I try to use a in memory persistent store or will that still be slow or cause an excessive memory penalty?

Try the sqlite store first, and then get back to us.

Can I ask why don't bindings lock the bound MOC or provide the option to? I had assumed (incorrectly) that bindings would handle threads OR provide some means to control or configure its threading behavior.

As far as I know, Bindings does not under any circumstances, and that, basically your view objects are all pinned to the main thread. I believe all the view and controller classes are fundamentally designed around NSRunloop.

File bugs.  Telling me doesn't help, because this is outside my area.

To be fair to Bindings, I don't think locking the MOC is a great solution. Background threads could starve the main/UI thread which would be bad. Fixing Core Data so you didn't have to save before passing objectIDs to the UI's MOC seems a much better idea, imo.

Why doesn't core data support locking at a finer grain? Or to rephrase, it would be very helpful if Core Data could lock at a ManagedObject level.

There lies dragons.  Fine grained locking doesn't work.

Start here and get back to me:
(0) <http://lists.apple.com/archives/cocoa-dev/2007/Mar/msg00739.html>

(1) a great article by Edward Lee from UC Berkeley. The canonical "why threads suck" and what we could do about it article.
<http://www.computer.org/portal/site/computer/menuitem.5d61c1d591162e4b0ef1bd108bcd45f3/index.jsp?path=computer/homepage/0506&file=cover.xml&xsl=article.xsl>

(2) Article on serious performance optimizations for multicore machines. It discusses several practical techniques like lock striping that ObjC and CF now use:
<http://developers.sun.com/learning/javaoneonline/2006/coolstuff/TS-5354.pdf>

(3) "Java Concurrency in Practice" The first really good book about multi-threading *engineering* instead of theory or APIs
<http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1206565296&sr=8-1>

(4) "Pattern Language for Parallel Programming" Basically, the Gang of 4 design patterns book, done for parallel programming. Not quite as good as "Design Patterns" (which you're crazy if you haven't yet read), but then, what is ?
<http://www.amazon.com/Patterns-Parallel-Programming-Software/dp/0321228111/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1206565387&sr=1-1>


I expected there to be a locking or transaction mode where I can lock it while I fill in an object. Nothing else should require me to worry about core data getting corrupted with multiple threads.

Sounds like a feature request you should file. There are better ways to implement this than locking at the NSManagedObject level.

I have interpreted that to mean that locking the managedObjectContext would be sufficient. I hadn't realized that bindings would try to obtain locks.

No, it doesn't.  But it needs to obtain locks to honor your locking.


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/2007/May/msg00222.html>
<<http://lists.apple.com/archives/cocoa-dev/2008/Jan/msg01889.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.

Are you describing in general or specifically with Core Data? Can you give more insight on this? Are you saying that I manually track changes from core data?

For updates objects, you can just pass a dictionary of deltas between threads if you don't want to save.

For inserted objects, you'd need a proxy insert. But, yes this works generally and with Core Data (although not conveniently).

Both KVC and Core Data have methods to make this somewhat less painful.

Manually tracking changes from Core Data is pretty easy. We post the NSManagedObjectContextObjectsDidChangeNotification every time you call -processPendingChanges.

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

But isn't a notification received on the same thread on which it was posted?

Yes, but that's not what the API is for. It takes the notification object, and merges it into the current MOC's state.

You could grab the notification object from the save on your background thread, and pass it to the main thread with -performSelectorOnMainThread: and this method will merge all the changes into the main thread's MOC.

It still requires inserts be saved, but otherwise handles all the merging logic efficiently.

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

File a bug about what?

Everything you don't like. Documentation, example code, Core Data, Bindings, performance, enhancements, feature requests ...

Do you consider the threading behavior in bindings and Core data to be a bug?

This is about what you consider to be suboptimal.
--

-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