UPDATED 2008-12-26: in general, all AppKit code should be called on the main thread.
Problem:
When using an NSAlert
to display a sheet in a multi-threaded application, unexpected badness can happen.
I was using
beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo:
To display an NSAlert
as a sheet.
But when the sheet appeared, the window it was attached to disappeared and got into some weird broken state where it would appear iff the application was not frontmost.
Fortunately, I remembered having encountered weirdness with NSAlert
sheets before. The symptoms were different (previously the alert didn’t have focus), but the same solution still worked.
Solution: make sure the message to display the sheet is sent by the main thread. To do this, put the call to beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo:
inside another method, showMyAlert
, then use performSelectorOnMainThread:withObject:waitUntilDone:
to make sure showMyAlert
is called on the main thread.
Work around use runModal
to display the alert as a modal dialog instead of a sheet. runModal
Does not appear to have any problems when called from other threads.
Just like last time:
The whole incident feels funny to me. I suspect there may be some deeper issue at work that I am not aware of. When I have time to investigate further I shall update this post. Unfortunately I don’t have time to look into ‘solved’ bugs today.
UPDATED 2008-12-26: in general, all AppKit code should be called on the main thread.