Reverting NSPersistentDocuments

NSPersistentDocument is documented to implement some extra work on top of NSDocument to handle the Core Data stack. The docs say:

Revert resets the document’s managed object context. Objects are subsequently loaded from the persistent store on demand, as with opening a new document.

That sounds a little painful! -reset is a pretty hardcore thing to do; how will my UI cope? Perhaps the description for -revertToContentsOfURL:ofType:error: will help?

Overridden to clean up the managed object context and controllers during a revert.

Ooh, cleaning up controllers sounds pretty magical! But, er, how? What? Are we talking about NSArrayController etc.? Who knows!

Finally, the Lion release notes have this to say:

• Overriding -revertToContentsOfURL:ofType:error:

When you enable autosaving in place you also enable version preserving. (Unless you also override +preservesVersions to turn version preserving off.) With autosaving in place enabled it's more important than ever to invoke super when you override -revertToContentsOfURL:ofType:error:, because it's NSDocument's default implementation of that method that updates the document's state to reflect what happens during reverting to an old version. If you don't, NSDocument might present the user with alerts about the document having been changed by another application when that is not the case.

Does NSPersistentDocument call super, or provide its own, equivalent (one hopes!) implementation?

Well, fortunately for you, I have done some digging — albeit in the pub, so bear that in mind.

How does NSPersistentDocument revert the managed object context?

It does indeed call -reset

How does the UI cope?

Before resetting the context, all window controllers are torn down. After the reset, -makeWindowControllers is called to recreate whichever windows the document pleases.

I think this is a reasonable compromise to make; while Cocoa is theoretically capable of keeping the same window intact and updating it to match the reverted model, that's going to be quite a pain to implement. Plus under Lion, with animated window opening and closing, the effect is quite instructive/pleasing.

Is -[NSDocument revertToContentsOfURL:ofType:error:] called?

Yes indeed, which in turn calls -readFromURL:ofType:error:, so make sure if you've overridden that, you can handle reading having already happened.

How does all this come into play with Versions on Lion?

When using the Versions browser, if the user chooses to revert back to an older copy of the document, Cocoa will call -revertToContentsOfURL:ofType:error: on your existing document. It won't take the easy route of throwing away the the document and starting again; in fact I can't find a suitable API for going down this route if you'd prefer.

© Mike Abdullah 2007-2015