基本的な NSDocument ベースのアプリがあります。次の場合、ドキュメントに最後の変更を加える必要があります。
- ユーザーがドキュメントのウィンドウを閉じる
- ユーザーがアプリを終了する
なんで?
ドキュメント ウィンドウには 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 に最後の変更を加えて、自動的に保存するにはどうすればよいですか?