NSPersistentDocument 中的 NSTextView 在失去第一响应者之前不会更新脏标志

Posted

技术标签:

【中文标题】NSPersistentDocument 中的 NSTextView 在失去第一响应者之前不会更新脏标志【英文标题】:NSTextView in NSPersistentDocument doesn't update dirty flag until loses first responder 【发布时间】:2013-03-17 20:06:48 【问题描述】:

我在NSPersistentDocument 窗口中有一个NSTextView。我将文本字段的内容绑定到“二进制数据”核心数据字段,但是当我在文本视图中键入文本时,文档的标题栏不会显示“已编辑”,直到文本视图失去焦点。因此,如果我在进行编辑后退出,则不会保存新数据。

如果我将NSContinuouslyUpdatesValueBindingOption 标志传递给文本视图绑定,“已编辑”会立即出现,但在长文档中性能确实会受到影响。

我如何让 Core Data 知道有未保存的更改而不实际分配每个更改的所有文本数据?

(这个问题类似于“Binded NSTextField doesn't update the entity until it lose the focus”,除了我不能使用NSContinuouslyUpdatesValueBindingOption,因为它使编辑操作非常慢。)

【问题讨论】:

【参考方案1】:

据我所知,我认为这是不可能的。 当您将更改分配给 NSManagnedObject 的属性时,CoreData 会为您管理状态(和撤消的东西)。如果您只是尝试在没有数据的情况下更改目录,则潜在的保存操作将不起作用。

看看“The Document Architecture Provides Undo Support for Free”是如何实现脏状态和撤消支持的。

如果您有非常大的文本文档,我建议您不要将它们存储在 CoreData 属性中。正如您在“Incremental Data Reading and Writing”中看到的那样,我建议将文本存储在单独的文件中并使用 NSFileWrapper。至少我将此解决方案用于我的应用程序。

这是顺便说一句。 CoreData 本身的建议 here “...但是,如果您能够将 BLOB 作为资源存储在文件系统上,并维护这些资源的链接(例如 URL 或路径),那就更好了。然后您可以加载必要时使用 BLOB”

我不知道您的 NSTextView 中有什么样的文本,但您使用的是“长文档”。

【讨论】:

【参考方案2】:

如果您将“NSTextView”子类化,您可以捕获"insertText:" 方法,然后在输入字符后立即设置"document Edited" flag of the document,而无需执行繁重(和CPU 密集型)绑定.

【讨论】:

setDocumentEdited: 是 NSWindow 方法,而不是 NSDocument 方法。当您更新文档的更改计数时,文档会自动调用它;基于文档的应用程序永远不需要直接发送窗口setDocumentEdited:。 (其实我想知道setDocumentEdited:的描述是不是比NSDocument更老。) 所以您还建议添加一个挂钩以在触发保存时手动更新 Core Data 模型?由于设置了窗口的documentEdited 标志,Core Data 会知道需要保存吗?

以上是关于NSPersistentDocument 中的 NSTextView 在失去第一响应者之前不会更新脏标志的主要内容,如果未能解决你的问题,请参考以下文章

使用 NSPersistentDocument 创建“文档”

创建持久存储时 NSPersistentDocument 崩溃

NSPersistentDocument:浏览版本:尝试添加只读文件

如何为 NSPersistentDocument 窗口赋予标题

撤消麻烦:以编程方式初始化`NSPersistentDocument`,标题栏中没有“已编辑”标志

NSPersistentDocument 和 NSArrayController 与 MagicalRecord