I know everyone is going to say don't do this but I really need to do this. I need to duplicate the behavior of NSApplication run's event handling. What the docs say about subclassing run is "This a critical and complex task, however, that you should only attempt with good reason." with no further information. I've got a good reason and I can get into more detail about why later if necessary.

My app is a cross platform app (Mac, Windows, and Unix) that all run in a single thread and share the same event handling model--the app controls the event loop. The app has an "engine" that controls everything such as processing commands, creating graphs, running scripts, displaying help files, etc. 90% of the app's functionality must run through the engine which are submitted as commands. Although most of the engine is not reentrant, it makes sure it's in a safe state when it polls in case the GUI needs to, for example, create and display a programmable dialog from a script on disk that describes the dialog while it's already creating a complicated graph.

It's not practical to rewrite this behavior in the app although we're taking steps towards instancing up the engine. However, it'll be quite some time before that happens and our users are clamoring for the 64-bit version of our app now (necessary for the huge amount of data they work with).

I've been working on porting my Carbon app to Cocoa for 64-bit support. Because NSApplicationMain() (and namely, NSApplication run) never returns, I created a separate worker thread for the engine to run in (the old polling logic is macro'd to nothing). It's constantly looping waiting for commands to be submitted to it (it does idle when necessary though). This works great but the problem is that the engine is not thread-safe. Since neither is AppKit, I'm constantly having to make sure methods perform in the right thread otherwise I get crashes. I'm still going through my code to do this and it's really tedious. This biggest issue is that I've found the GUI to be quite sluggish in some instances. For example, the GUI may respond to an event by performing code in the worker thread (without waiting, a must) which may in turn may perform GUI methods in the main thread (while waiting). Not waiting for methods to perform in the main thread speeds things up a little but I haven't confirmed whether that's safe yet.

So I've decided to investigate going back to the original single- threaded polling model. To avoid being blocked by NSApplication run, I duplicated the behavior of NSApplicationMain() and part of run by initializing my NSApplication instance, loading my main nib, then invoking finishLaunching. Control then goes to my engine as before. I poll using nextEventMatchingMask:untilDate:inMode:dequeue: and sendEvent:. I just added this earlier today and my app seems to be running OK, is much snappier in the situations where it was sluggish in the multi-threaded model, and I haven't observed any memory leaks. However, I noticed that after a closing a window, the previous key window does not become key. I can add code to handle this but I'm concerned there are other things going on in NSApplication's run method do/while loop that I'm missing. Can anyone tell me what else I need to do in my event loop?

Again, I can get into more detail about why my app has to behave the way it does for clarification.

-Chinh Nguyen
 cngu...@stata.com

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to