У меня есть многопоточное приложение, в котором одновременно выполняется много одновременных операций. Когда каждый поток завершается, он вызывает один из двух методов основного потока
performSelectorOnMainThread:@selector(operationDidFinish:)
// and
performSelectorOnMainThread:@selector(operationDidFail:withMessage:)
При сбое операции я запускаю лист с сообщением об ошибке и предоставляю пользователю две кнопки: «отмена» и «повторить попытку». Вот код, который я использую для запуска листа:
// failureSheet is a NSWindowController subclass
[NSApp beginSheet:[failureSheet window]
modalForWindow:window
modalDelegate:self
didEndSelector:@selector(failureSheetDidEnd:returnCode:contextInfo:)
contextInfo:nil];
Проблема заключается в том, что если одновременно происходит сбой 2 одновременных операций, то отображаемый текущий лист перезаписывается последним сообщением об ошибке, а затем действие пользователя «повторить попытку» будет только повторять последнюю неудачную операцию. В идеале я хотел бы «поставить в очередь» эти листы сбоев. Если 2 операции завершаются неудачей одновременно, вы должны видеть 2 листа один за другим, что позволяет пользователю отменить или повторить их по отдельности.
Я пытался использовать:
[NSApp runModalSessionForWindow:[failureSheet window]]
, который, кажется, делает то, что я хочу, но не работает в моей ситуации. Может быть, это не безопасно поток?
Например, работает следующий код ...
- (void)displaySheet
{
[NSApp beginSheet:[failureSheet window]
modalForWindow:window
modalDelegate:self
didEndSelector:@selector(failureSheetDidEnd:returnCode:contextInfo:)
contextInfo:nil];
[NSApp runModalForWindow:[failureSheet window]];
[NSApp endSheet:[failureSheet window]];
[[failureSheet window] orderOut:nil];
}
// Calling this method from a button press works...
- (IBAction)testDisplayTwoSheets
{
[self displaySheet];
[self displaySheet];
}
Однако, если у меня есть 2 разные многопоточные операции, вызывайте displaySheet (в главном потоке), когда они завершены, я вижу только один лист, и когда я закрываю его, модальный сеанс все еще выполняется, и мое приложение по существу застряло.
Какие-нибудь предложения относительно того, что я делаю неправильно?