Modal NSAlert dentro do bloco não exibido
-
12-12-2019 - |
Pergunta
Em meu aplicativo baseado em documento, substituí o método openDocument:na minha subclasse de NSDocumentcontroller para que eu possa exibir meu próprio openPanel.Passo as URLs escolhidas para o método openDocumentWithContentsOfURL:display:completionHandler:.Eu uso este código para a chamada:
[self openDocumentWithContentsOfURL:[chosenFiles objectAtIndex:i] display:YES completionHandler:^(NSDocument *document, BOOL documentWasAlreadyOpen, NSError *error) {
if (document == nil)
{
NSAlert* alert = [NSAlert alertWithError:error];
[alert runModal];
}
}];
Então, quero exibir o erro passado se nil for retornado como referência ao documento.O problema é que o programa simplesmente "congela" depois de pressionar o botão "Abrir" no painel aberto.Então preciso interromper manualmente o programa com o botão "parar" no Xcode.Nenhuma bola de praia giratória aparece, no entanto.Se eu comentar a linha "[alert runModal]", o programa não congela mais, mas nenhum alerta é exibido, é claro.
Agora o estranho:O código funciona às vezes.Se eu mudar do Xcode para o navegador e voltar e executar o programa novamente, às vezes ele funciona perfeitamente e o erro é exibido.Depois de algum tempo ele para de funcionar novamente.É imprevisível, mas na maioria das vezes não funciona.
Tudo isso me parece uma condição de corrida.Certamente tem algo a ver com o bloco?Mas o que eu faço de errado?
Solução
Convertendo meu comentário em uma resposta:
runModel no thread principal.
[alert performSelectorOnMainThread:@selector(runModal) withObject:nil waitUntilDone:NO];
Acho que runModel precisa ser chamado no thread principal porque faz parte da estrutura do AppKit e está acionando essencialmente gráficos de UI.Acredito que todas as chamadas para o framework AppKit ou para qualquer método que manipule gráficos precisam estar no thread principal.