Re: NSConnection, where'd my proxy go?
Re: NSConnection, where'd my proxy go?
- Subject: Re: NSConnection, where'd my proxy go?
- From: Bill Bumgarner <email@hidden>
- Date: Sat, 8 Jun 2002 01:44:09 -0400
Date: Fri, 07 Jun 2002 15:34:29 -0700
Subject: NSConnection, where'd my proxy go?
From: Chris DeSalvo <email@hidden>
To: <email@hidden>
So I'm following everyone's suggestion and doing my multi-thread messaging
with distributed objects through NSConnection.
Everything seems to be fine, except my worker thread can't seem to, well,
make the connection.
My initial setup is happening in the main thread thusly:
threadReceivePort = [[NSPort port] retain];
threadSendPort = [[NSPort port] retain];
appkitConnection = [[NSConnection alloc]
initWithReceivePort:threadSendPort sendPort:threadReceivePort];
[appkitConnection registerName:@"D2_PROXY"];
[appkitConnection setRootObject:self];
Then in the worker thread I'm trying to make calls thusly:
conn = [NSConnection connectionWithRegisteredName:@"D2_PROXY"
host:nil];
proxy = (D2Controller *) [conn rootProxy];
The connection is found, and conn is non-nil. However, proxy comes back
nil. I've tried about a million little tweaks for the ordering of things
and it just never works. Calling rootProxy always returns nil no matter
what I do.
If everything is running within a single application, there is no need to
register and advertise a named connection for intra-thread
communication. In the main thread:
... (applicationDidInitialize or some such early point) ...
threadReceivePort = [[NSPort port] retain]; //ivar
threadSendPort = [[NSPort port] retain]; // ivar
appkitConnection = [[NSConnection alloc]
initWithReceivePort:threadSendPort sendPort:threadReceivePort];
[appkitConnection setRootObject:self]; // self is -retain'd and won't
go away
....
The thread connects to the MEL thread by executing the following *in the
thread*:
....
serverConnection = [NSConnection
connectionWithReceivePort:threadReceivePort sendPort:threadSendPort];
appkitProxy = [[serverConnection rootProxy] retain];
[appkitProxy ...do stuff...];
....
The thread within which the first hunk of code was executed *must* have a
running NSRunLoop-- the AppKit's main event loop, for example-- for any of
the method invocations from the worker thread to be properly invoked in
the other thread of execution. Note that the order of the receive and
send ports are backwards between the two hunks of code.
If you read the docs for NSConnection closely, it indicates that
+defaultConnection should be used if you want to vend objects via a named
connection and that there are some implications as to the sending and
receiving port's configuration. Assuming communication is to remain
within a single task, there is no need to name the port and the above code
will work fine.
<Rant On>
Ugh, safely sending messages between threads shouldn't be this hard. I'm
also still amazed that after 15+ years of development all of the NextStep
UI
frameworks aren't thread-safe.
Making the UI layer thread safe buys the developer very little... forcing
all UI interaction into a single thread forces the issue to a granularity
that is a hell of a lot easier to deal with in that you don't end up with
a pile of user generated events interleaved with the already complex tasks
associated with keeping multithreaded execution both sane and efficient.
Communicating between threads in a non event driven context-- i.e. in a
simple queue based or condition based system -- is significantly less
complex (communicating between threads via DO is even easier, once you
work through some of the nasty little gotchas).
This is not to say that it wouldn't be a boon for the AppKit to be thread
safe, just that doing so would require a tremendous amount of engineering
effort that is much better utilized fixing and refining many other aspects
of the AppKit and surrounding environment.
In general, developers tend to use multithreaded architectures as an
answer to performance problems that they don't actually have. Worse,
multithreading an application more often than not leads to a level of
complexity and fragility that most developers are incapable of dealing
with effectively. In the end, a lot of well intentioned effort to
achieve greater performance or responsiveness through threading simply
leads to an application that is either intermittently unstable or has so
many points of synchronization that it might as well be single threaded.
Multithreading is hard, regardless of how much syntax is added to a
language in direct support of threading. Attempting to use it without
fully understanding why threading will yield an advantage or *exactly* how
the the various threads of execution will interact is a recipe for
disaster.
If anyone person on thread-heavy project makes a single wrong assumption,
the application will exhibit behavior that can be incredibly difficult to
diagnose and even worse to fix.
I have seen many projects either fail outright or yield solutions with
sub-par performance because of issues that arose from the improper use of
threads. If the project yielded a working application (or applications),
the threading became a mostly moot point in that synchronization between
the threads caused the app to behave more like it was single threaded
anyway.
Again-- certainly, having a thread safe AppKit will be a welcome upgrade
to the development environment, but it is not the panacea that so many
developers tend to believe it can be.
Threads are a useful and powerful tool, but they come with a significant
price.
<Rant Off>
b.bum
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.