0

I've a multithreaded OSX application that is showing an NSAlert window. Most of the cases the UI seems fine but sometimes it breaks down the UI by misplacing the button which looks very ugly.

enter image description here

As i can't block the main thread and don't want to show it as modal. I'm using the following code.

NSAlert* alert = [NSAlert alertWithMessageText:title defaultButton:defaultBtn alternateButton:alterBtn otherButton:otherBtn informativeTextWithFormat:msg];
[alert setAlertStyle:style];

BOOL isMainThread = (dispatch_get_current_queue() == dispatch_get_main_queue());

if(isMainThread)
    [alert layout];
else
{
    dispatch_sync(dispatch_get_main_queue(), ^{
        [alert layout];
    });
}

NSModalSession session = [NSApp beginModalSessionForWindow:alert.window];
__block NSUInteger response;

for (;;) {
    if(isMainThread)
    {
        response = [NSApp runModalSession:session];
    }
    else
    {
        dispatch_sync(dispatch_get_main_queue(), ^{
            response = [NSApp runModalSession:session];
        });
    }

    if(response != NSRunContinuesResponse)
        break;
}

Any idea why this is happening?

Prince
  • 21
  • 1
  • 2

1 Answers1

1

Wow, that is some seriously messed code you have there.

  • How did you decide calling -layout was a necessary of a good idea?
  • AppKit is not thread safe; you should not call -beginModalSessionForWindow: from any thread but the main one
  • NSAlert is not designed to let you run a modal session for it, or take over presentation of it

Instead, call NSAlert directly on the main thread with either -runModal or -beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo:

Mike Abdullah
  • 14,933
  • 2
  • 50
  • 75