3

Cocoa アプリケーションにカスタムの終了動作を実装しようとしています。通常、アプリケーションが正常に終了すると、実行時のデータベースの最終クリーンアップが実行されてから終了します。これは、が呼び出されるNSApplicationたびに AppDelegate ( のデリゲート) 内で発生します。[NSApp terminate:aSender]

- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
    // database cleanup...
    return NSTerminateNow;
}

実行時にエラーが発生した場合 (データベース ファイルが削除された場合など)、ユーザーにエラーを提示し、回復 (ファイルを元に戻して再試行) または終了するオプションを提供します。[終了] が選択されている場合は、データベースのクリーンアップをすべてスキップしてアプリを終了します。これは不可能になったためです。本質的に、私はこのようなものが欲しいです:

- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
    BOOL gracefulTermination = ...;

    if (gracefulTermination == YES)
    {
        // Database cleanup....
    }

    return NSTerminateNow;
}

もちろん、問題は gracefulTermination の値を取得することです

infoDict などの呼び出されNSAppたときにカスタム変数を渡し、内部で受け取る方法はありますか?terminate:applicationShouldTerminate:

そうでない場合、カスタムの終了動作を実現するためのより良い方法はありますか?


私の知る限り、terminate:が他のオブジェクトから呼び出されると、次のようになります。

  1. [NSApp terminate:self];foo (別名self )によって呼び出されます。
  2. NSApp はデリゲートを送信します: [aDelegate applicationShouldTerminate:self];( selfはfooではなく NSApp です)。
  3. aDelegate はメッセージを受け取り、applicationShouldTerminate:実装されている場合は実行します。

fooはどこかに消えたように見え、aDelegateがメッセージを受け取るまでに、それは完全になくなり、送信者としてのみNSApp表示されます。これにより、カスタム動作を含む aDelegate に foo 内の infoDict や単なる infoDict を渡すことができなくなりterminate:ます。


[NSApp terminate:...]のようなものを使用せずに終了できることは承知していexit()ます。私が読んだところによると、これはココアのコーシャではないため、眉をひそめています. さらに、他のクリーンアップ操作が内部applicationShouldTerminate:で発生するのを防ぐことにもなります。

4

1 に答える 1

3

理想的な解決策は、アプリのデリゲートが終了を許可されているかどうかを判断できるようにアプリを構成することです。

アプリケーション デリゲートがこの情報に他の方法でアクセスできないと仮定すると (たとえば、終了をトリガーしたオブジェクトが発生するかどうかに影響します)、これが最も簡単な解決策のように思えterminationInfoますterminate:。プロパティを呼び出し、super を呼び出します。

于 2010-08-04T18:15:57.017 に答える