Search code examples
cocoacore-datacocoa-bindingsnstextview

NSTextView in NSPersistentDocument doesn't update dirty flag until loses first responder


I have an NSTextView in an NSPersistentDocument window. I bind the text field's contents to a "binary data" Core Data field, but when I type text into the text view, the document's title bar doesn't say "Edited" until the text view loses focus. Thus, if I quit after making an edit, the new data isn't saved.

If I pass the NSContinuouslyUpdatesValueBindingOption flag to the text view binding, "Edited" appears immediately, but performance really suffers in long documents.

How do I let Core Data know that there are unsaved changes without actually assigning all the text data on every change?

(This question is like "Binded NSTextField doesn't update the entity until it lose the focus" except I can't use NSContinuouslyUpdatesValueBindingOption because it makes editing operations very slow.)


Solution

  • I think this is not possible as far as i understood. When you assign the changes to a property of a NSManagnedObject, CoreData manage to diry state (and the undo stuff) for you. If you just try to change the diry without the data a potential save operation will not work.

    Take a look into "The Document Architecture Provides Undo Support for Free" how the dirty state and the undo support are implemented.

    If you have really large text documents, i suggest you should not store them in a CoreData property. As you can read in "Incremental Data Reading and Writing" i suggest to store the text in a separate file and use a NSFileWrapper. At least I use this solution for my application.

    This is btw. what CoreData itself suggest here "...It is better, however, if you are able to store BLOBs as resources on the filesystem, and to maintain links (such as URLs or paths) to those resources. You can then load a BLOB as and when necessary"

    I don't know what kind of text you have in your NSTextView but you was taking about "long documents".