Re: NSOutlineView threading problem
Re: NSOutlineView threading problem
- Subject: Re: NSOutlineView threading problem
- From: Bill Bumgarner <email@hidden>
- Date: Sun, 15 Jun 2008 21:41:08 -0700
On Jun 15, 2008, at 8:05 PM, David wrote:
On Sun, Jun 15, 2008 at 8:46 PM, Bill Bumgarner <email@hidden> wrote:
I would highly recommend that you look long and hard at how are you
are managing the data structures that are also used by
NSOutlineView. In particular, if you are futzing with an
NSMutableArray from one thread while the AppKit is enumerating it in
another, that can be very problematic. In particular,
NSMutableArray may effectively realloc() its contents as it crosses
certain capacity thresholds. If the other thread happens to be in
the middle of reading from the old buffer at that time, well...
*boom*.
Thanks for the good example of a specific threading issue. In my
case, the outlineview is using my code as the data source. I can
control how I access the NSMutableArray. I do not enumerate the
array in that code. If I wanted to be safe, I should be ok putting
locking around my use of the array since I'm the one populating it
and I'm the one reading it in behalf of the outlineview. That should
be sufficient. The outlineview doesn't have any other mystical
connection to the arrays other than through my data source.
Correct -- assuming the items in the mutable array are also thread-
safe, then locking around access to said array should be sufficient as
long as *nothing* outside of your code has access to said array.
I'm still having heartburn with some things in Cocoa. I came from
the Java world. I was excited to hear about CoreData and bindings
and all this high power stuff. But I ran into threading issues with
core data which made it not practical for my usecase. And I needed
more flexibility than is documented with bindings. So now I've
downshifted to using a data source, which is similar to the normal
approach in Java.
CoreData is actually an extremely high performance framework in the
face of threading, as long as you play by the rules. And the rules
are designed to allow for very flexible program design. Where the
rules limit certain design patterns, it is often the case that such a
pattern would require so much locking overhead in the traditional
threaded case that the performance would be horrible anyway.
I let Ben speak to the details if he desires. Or you can read the
archives:
http://www.cocoabuilder.com/archive/message/cocoa/2007/5/6/182874
Threading is hard for me to comprehend in the objective-c world. In
Java, threading is powerful and relatively simple to implement with
simple relatively consistent rules and many classes which are thread
safe. Cocoa seems to have thrown in the towel on threading and
completely leaves it up to the developer. This leads to solutions
earlier proposed to use performSelectorOnMainThread. That solution
reminds me of the ancient Windows 3.0 days on DOS when there was no
real threading support and you had to perform all operations in
little chunks so you could go back to the event loop and see if a
more important event had come in.
Threading is powerful. It doesn't need to be as hard as Cocoa has
made it. Java makes it easy. It reminds me of garbage collection.
Never have to think about it in Java. It just works. But in Cocoa,
garbage collection was finally just implemented. Maybe someday
they'll go back and do some basic thinking about threads and make it
easier to write thread safe code using Cocoa. As it stands its a
nightmare if something as trivial as an Array isn't even thread safe.
For the record: NSArray is thread safe. NSMutableArray is not.
Why? Because making NSMutableArray thread safe would make many common
array operations brutally slow whereas NSArray is inherently read-only
and (in this context -- not all read-only environments are the same!)
thus can be optimized for lockless thread safety.
I find any claim that something made threading easy to be suspect.
In particular, I suspect that "easy threading" equates to "performance
sucks, but at least you can call the API from any thread at any
time". That had certainly been my experience in the decade or so of
Java development I did; I ran into dozens of apps that claimed to be
fully threaded for performance readings. Yet, the performance sucked
and a brief bit of analysis with a decent perf tool showed that most
of the threads were spending most of the time waiting on locks --
often, better performance could have been had with limited or no
threading at all!
Java *can* achieve excellent performance in multithreaded
environments, but it is not easy to do. Not by a long shot. Here is
an excellent book on the subject (thanks, Ben!): Java Concurrency in
Practice" by Brian Goetz.
GC is similar. In Java, I ran into quite a few programs where the
developers had chosen to "never have to think about it" when it comes
to GC. Yet, there apps were regularly crashing due to lack of scarce
resources. Of course, they would often naively throw more RAM at the
problem only to find that the app crashed faster.
Why?
Because they didn't think about GC. In particular, they didn't think
that intermingling memory reclamation with scarce resource management
is a terrible idea. Example: that closing a file descriptor in
finalize() method is simply asking for trouble.
You are correct that Objective-C leaves much of the details of
threading up to the developer and, certainly, there are any number of
potential refinements that could better serve the needs of threaded
development. And Apple is doing exactly that with the introduction
of Grand Central in Snow Leopard, something that has much greater
potential reward (unfortunately, not something that can be discussed
on this list).
b.bum
Attachment:
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________
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