views:

291

answers:

2

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?

A: 

You can create your UI programatically if you don't want to use Interface Builder. I do this for some stuff. Interface Builder is better for quickly laying out a basic window though.

Maybe this section of the reference documents will clear some issues up for you? http://developer.apple.com/mac/library/documentation/cocoa/reference/Foundation/Classes/NSRunLoop_Class/Reference/Reference.html

darren
This doesn't answer his question at all.
Georg
+7  A: 

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.

bbum
tl;dr version: "Cocoa is a single-threaded UI toolkit like WPF, do work on other threads"
Paul Betts
Cute, but incorrect. Cocoa actually has a bunch of support for multithreading, including multithreaded drawing. What it doesn't do is to have multiple threads handling events independently (because, largely, that doesn't make sense).
bbum
@bbum that's what I meant, that unless you force it, Cocoa will have 1 event loop for processing UI messages. My tl;dr; version wasn't so well explained, but I was trying to keep it short :)
Paul Betts