2012-06-20 3 views
0

У меня многопоточное приложение OSX, в котором отображается окно NSAlert. В большинстве случаев пользовательский интерфейс кажется прекрасным, но иногда он нарушает пользовательский интерфейс, помещая кнопку, которая выглядит очень уродливо.NSAlert показывает неуместные кнопки

enter image description here

Как я не могу блокировать основной поток и не хотите, чтобы показать его как модальный. Я использую следующий код.

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; 
} 

Любая идея, почему это происходит?

ответ

1

Ничего себе, это какой-то серьезно перепутанный код, который у вас там есть.

  • Как вы решили позвонить -layout - это была необходима хорошая идея?
  • AppKit не является потокобезопасным; Вы не должны вызывать -beginModalSessionForWindow: из любого потока, но главный один
  • NSAlert не предназначен, чтобы запустить модальную сессию для него, или взять на себя презентацию его

Вместо этого вызовите NSAlert непосредственно в главном потоке либо -runModal, либо -beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo:

+0

Вы не должны использовать модальные сеансы вообще. Этот конкретный API неофициально устарел. –