I need to imlement in cocoa, a design that relies on multiple threads.
I started at the CoreFoundation level – I created a CFMessagePort and attached it to the CFRunLoop, but it was very inconvenient as (unlike on other platforms) it needs to have a (systemwide) unique name, and CFMessagePortSendRequest does not process callbacks back to the current thread while waiting. Its possible to create my own CFRunLoopSource object, but building my own thread safe queue seems like overkill.
I then switched from using POSIX threads to NSThreads, calling performSelector:onThread: to send messages to other threads. This is far easier to use than the CFMessagePort mechanism, but again, performSelector:onThread: does not allow the main thread to send messages back to the current thread – and there is no return value.
All I need is a simple – inprocess – mechanism (so I hopefully don’t need to invent schemes to create ‘unique’ names) that lets me send a message (and wait for a reply) from thread A to thread B, and, while waiting for the message, allow thread B to send a message (and wait for a reply) to/from thread A.
A simple: A calls B re-entrantly calls A situation that’s so usual on a single thread, but is deadlock hell when the messages are between threads.
use -performSelectorOnThread:withObject:waitUntilDone:. The object you pass would be something that has a property or other “slot” that you can put the return value in. e.g.
If you want to be really sophisticated about it, instead of passing an object of a class you define, use an NSInvocation object and simply invoke it on the other thread (make sure not to invoke the same NSInvocation on two threads simultaneously) e.g.
Edit
if you don’t want to wait for the processing on the other thread to complete and you want a return value, you cannot avoid the other thread calling back into your thread. You can still use an invocation e.g.
If you don’t like to create a new class to pass the thread and the invocation, use an NSDictionary instead e.g.
Be careful about object ownership. The various performSelector… methods retain both the receiver and the object until they are done but with asynchronous calls there might be a small window in which they could disappear if you are not careful.