views:

53

answers:

1

I have a multi-threaded Cocoa app that processes images. The program has a progress bar and some text showing how far along the process is. This all works great. However, sometimes the interface will just freeze up and everything will stop updating. The progress bar stops moving, and the text stops updating in the percentage counter. However, the actual process is still working! I have an NSBeep() that fires when the program is finished, and I still hear that even though the UI is no longer being updated. It's as though the UI just disconnects from the code.

Another weird problem is that sometimes the NSOpenPanel that opens when the user wants to choose a file will just be a white void. I declared the NSOpenPanel (I'm using [NSOpenPanel openPanel]) in the main thread, which helps (I tried retaining it at first, but that didn't work). I don't know if this is related, but any ideas would be appreciated!

I am using Xcode 3.1.1 (GCC 4.2) on Mac OS X 10.5.8.

+4  A: 

You're trying to manipulate the UI from other threads. As stated in the docs, AppKit is generally not thread-safe and you should interact with your GUI on the main thread. See -performSelectorOnMainThread:withObject:waitUntilDone:.

Joshua Nozzi
That's exactly the answer I needed. I went back and updated my code to ensure none of the threads touch the UI. I've been testing it for the past few hours and it seems to work perfectly now! Thanks!
Synthetix
One other question: what if I need to query (not change) an NSButton for its state from a thread? Isn't this technically interacting with the UI?
Synthetix
You shouldn't. Your button should be setting some state within a controller. Ask the controller.
Joshua Nozzi
Got it. I connected the checkbox to a method that sets a BOOL variable in the app controller. I then check that from the thread instead of checking the IBOutlet directly. Thanks again!
Synthetix