0

基本的な NSDocument ベースのアプリがあります。次の場合、ドキュメントに最後の変更を加える必要があります。

  1. ユーザーがドキュメントのウィンドウを閉じる
  2. ユーザーがアプリを終了する

なんで?

ドキュメント ウィンドウには NSTextField が含まれています。通常、このテキスト フィールドに入力されたテキストは、ユーザーが ( 経由でtextDidEndEditing(_:)) Enter キーを押した後、ドキュメントのモデルにコミットされます。

ユーザーがテキストを入力したが、Enter キーを押さなかったとします。代わりに、Cmd-W または Cmd-Q を押して、ドキュメント ウィンドウを閉じるか、アプリを完全に終了します。

textDidEndEditingは呼び出されないので、テキスト フィールドに変更が含まれているかどうかを確認し、自分でドキュメントを更新しようとします。

❌ ここが難しいところです。次の場合、 でデッドロックが発生しNSDocument.performActivityWithSynchonousWaitingます。

override func viewWillDisappear() {
    super.viewWillDisappear()

    undoManager?.disableUndoRegistration()
    textField.commitEditing() // Updates the model

    document.updateChangeCount(.changeDone)
}

にフックするのではなく、 にフックすることで、デッドロックを回避することができviewWillDisappearましたNSDocument.canClose(withDelegate delegate: Any, shouldClose shouldCloseSelector: Selector?, contextInfo: UnsafeMutableRawPointer?)

✅ このコードにより、ユーザーがドキュメント ウィンドウを閉じたときに変更が保存されます。

override func canClose(withDelegate delegate: Any, shouldClose shouldCloseSelector: Selector?, contextInfo: UnsafeMutableRawPointer?) {

    undoManager?.disableUndoRegistration()
    textField.commitEditing() // Updates the model

    updateChangeCount(.changeDone)

    super.canClose(withDelegate: delegate, shouldClose: shouldCloseSelector, contextInfo: contextInfo)
}

.

❓残念ながら、上記はユーザーがアプリを終了したときに呼び出されません。--でドキュメントを更新しようとしましたが、うまくいきapplicationWillTerminate()ませんでした。また、終了をオーバーライドapplicationShouldTerminate()して 3 秒間遅らせてみました。ドキュメントのウィンドウが「編集済み」としてマークされているのがわかりますが、変更は保存されません。

アプリが終了する直前に NSDocument に最後の変更を加えて、自動的に保存するにはどうすればよいですか?

4

1 に答える 1