NSDocument は、引き続きソフトウェア メンテナンスの悪夢です。
特定のブロッキングダイアログを同期的に処理したいという問題を抱えている人はいますか?
BEGIN EDIT:同期的に待機できるソリューションを見つけたかもしれません
これが「Apple 承認済み」のソリューションであることを確認できる人はいますか?
static BOOL sWaitingForDidSaveModally = NO;
BOOL gWaitingForDidSaveCallback = NO; // NSDocument dialog calls didSave: when done
...
gWaitingForDidSaveCallback = true;
[toDocument saveDocumentWithDelegate:self
didSaveSelector:@selector(document:didSave:contextInfo:)
contextInfo:nil];
if ( gWaitingForDidSaveCallback )
{
// first, dispatch any other potential alerts synchronously
while ( gWaitingForDidSaveCallback && [NSApp modalWindow] )
[NSApp runModalForWindow: [NSApp modalWindow]];
if ( gWaitingForDidSaveCallback )
{
sWaitingForDidSaveModally = YES;
[NSApp runModalForWindow: [NSApp mbWindow]]; // mbWindow is our big (singleton) window
sWaitingForDidSaveModally = NO;
}
}
...
- (void)document:(NSDocument *)doc didSave:(BOOL)didSave contextInfo:(void *)contextInfo
{
[self recordLastSaveURL];
gWaitingForDidSaveCallback = NO;
if ( sWaitingForDidSaveModally )
[NSApp stopModal];
}
編集終了
Snow Leopard/Lion/ML をサポートする必要があります
アプリの終了は醜いプロセスです。ユーザーが終了することを決定し、ドキュメントに保存が必要な変更がある場合、私はこれを呼び出します:
gWaitingForDidSaveCallback = true;
[toDocument saveDocumentWithDelegate:self
didSaveSelector:@selector(document:didSave:contextInfo:)
contextInfo:nil];
私は本当にこの呼び出しを同期させたいと思っていますが、最新の Lion では、これによりアプリがハングします。
while ( gWaitingForDidSaveCallback )
{
// didSave: callback clears sWaitingForDidSaveCallback
// do my own synchronous wait for now
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceReferenceDate:0.05]];
}
ハングの私の最善の推測は、ウィンドウを閉じるボタンの mouseDown: が NSDocument を混乱させていることです。
そのため、ユーザーがさまざまな危険なホットキーを実行できないように、アプリのメイン ループに保守不可能なステート マシン ロジックを追加する必要があります。
よし、ニヤニヤして我慢すると、また障害物にぶつかる!
以前の OS バージョン/SDK では、[NSApp modalWindow] は、この状態にあるときにウィンドウを返します。今はそうではありません!うーん...
NSDocument には、この状態にあるときにテストする API がありません!
そのため、この状態をグローバルにチェックするメカニズムはありません! ステート マシンにさらに別のステート変数を追加する必要があります。
すべての OS バージョンと現在 (および将来) のすべての SDK で機能する、この問題に対するよりクリーンなソリューションを持っている人はいますか?