一度に多くの並行操作が実行されるマルチスレッドアプリケーションがあります。各スレッドが終了すると、メインスレッドの2つのメソッドのいずれかが呼び出されます
performSelectorOnMainThread:@selector(operationDidFinish:)
// and
performSelectorOnMainThread:@selector(operationDidFail:withMessage:)
操作が失敗した場合、エラーメッセージを表示するシートを起動し、「キャンセル」と「再試行」の2つのボタンをユーザーに表示します。シートを起動するために使用するコードは次のとおりです。
// 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(メインスレッド上)を呼び出す場合、1つのシートしか表示されず、それを閉じると、モーダルセッションはまだ実行されており、アプリは基本的にスタックしています。
私が間違っていることについて何か提案はありますか?