Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cocoa, Windows and Threads?

On windows, each thread has a message queue, and each message queue will process messages for the windows owned by that thread. This means that it is quite simple to write an application where you can create a thread, with a message loop, and one (or more) windows. Ignoring any kind of application issues, one now has application windows that will keep on interacting with the user even if one of the other windows is busy in some kind of modal operation.

Now, in porting the app to cocoa, I encounter, well, Interface Builder. Which is a surprise to someone who expects to be more in control of window creation and message loop construction. None the less I can see where IB is coming from.

My problem however, lies with the opaque funciton NSApplicationMain(). This - on the applications main thread, automatically creates the applications main window, and runs the message pump, all data driven nicely from the NIB files.

However, this leaves me with a problem: Even if I buy into the idea that Interface Builder is the way to go for making my main app window - and I have figured out enough objective C to create sub windows on the fly - as well as how to create threads - I can's see how to create a message pump in worker threads. I begin to doubt its possible.

Do windows in cocoa even have the kind of thread affinity they do In Win32? i.e. each thread has its own message dispatching loop for windows owned by that thread? Im beginning to suspect that perhaps Cocoa expects all my windows to be 'owned' by the main thread and I just get to offset work (and drawing) onto other threads.

Any clues as to how best to translate a multi window-per-thread Win32 app to Cocoa's paradigms?

like image 591
Chris Becke Avatar asked Jan 13 '10 22:01

Chris Becke


1 Answers

Interface Builder is a red herring in this discussion. The real question is centric to the design patterns of Cocoa and these two paragraphs from your question are key:

However, this leaves me with a problem: Even if I buy into the idea that Interface Builder is the way to go for making my main app window - and I have figured out enough objective C to create sub windows on the fly - as well as how to create threads - I can's see how to create a message pump in worker threads. I begin to doubt its possible.

Do windows in cocoa even have the kind of thread affinity they do In Win32? i.e. each thread has its own message dispatching loop for windows owned by that thread? Im beginning to suspect that perhaps Cocoa expects all my windows to be 'owned' by the main thread and I just get to offset work (and drawing) onto other threads.

In short, no, it doesn't work like that. Cocoa has a completely different event handling model and a completely different set of tools for supporting Concurrency.

Notably, Cocoa has a strong notion of a main event loop that runs always on the main thread. This is where user events are handled and where almost all drawing occurs (though this restriction has been loosened over time).

It is different and trying to bend it to work like the thread-per-window-with-pump is a path of extreme pain. Don't go down it.

Now, Cocoa does have run loops per thread. But they are not used to process user events.

In short, you are going to need to revisit the architecture of your application to pull the code over to Cocoa. A straight port isn't possible.

like image 100
bbum Avatar answered Sep 28 '22 06:09

bbum