Re: NSControllers, NSLocks, NSThread, Setters and Getters
Re: NSControllers, NSLocks, NSThread, Setters and Getters
- Subject: Re: NSControllers, NSLocks, NSThread, Setters and Getters
- From: Ken Thomases <email@hidden>
- Date: Thu, 22 May 2008 23:21:43 -0500
On May 22, 2008, at 10:56 PM, Todd Heberlein wrote:
I want to have a controller observe an object's variables accessed
through accessor methods, but I also want to set the value for those
variables via a separate NSThread. Furthermore, I want to protect
those variables via locks.
KVO change notifications are sent and received on the same thread
where the change is made. If an observer is not coded to expect this,
it will cause all sorts of problems. Almost no Cocoa classes are
designed to expect it. (An exception might be, for example,
NSOperationQueue which observes the properties of its NSOperations,
which by their nature will change on various threads.)
In particular, bindings to the GUI are not safe with respect to
changes made by background threads.
Can I use NSLocks inside the accessor methods that are being used by
NSControllers, or will this just really screw things up (other than
the many usual ways you can screw things up with multiple threads
and locks)?
I don't think using NSLocks inside the accessor methods will add to
the problem, but they don't solve it. For automatic KVO, the
notifications are sent outside your code and so aren't controlled by
the lock. Even if they were inside, they would still arrive
asynchronously with respect to the main thread, which might be doing
who-knows-what at the time. So, the NSController (or the view to
which it is bound) is almost certain to do something it shouldn't do
on a non-main thread.
One possible solution is for the background thread to use
[objectToChange performSelectorOnMainThread:@selector(set<key>:)
withObject:theNewValue ...]. That's cumbersome and represents way too
much coupling between your background thread and the main one. You'll
probably lose whatever performance advantage that a secondary thread
might provide.
Ideally, a background thread should be given all of the data it needs
to do its work at the beginning and it would work in isolation until
its job is done and only then provide results in a lump to the main
thread. Then the main thread would integrate those results into the
model, or whatever. I would recommend that you refactor your design
toward this approach. If you're targeting Leopard, NSOperation and
NSOperationQueue are designed with this approach in mind.
Cheers,
Ken
_______________________________________________
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