Re: Core Data + Undo + Autosave = Instability? Was: … Undo Delete : Cannot fulfill fault
Re: Core Data + Undo + Autosave = Instability? Was: … Undo Delete : Cannot fulfill fault
- Subject: Re: Core Data + Undo + Autosave = Instability? Was: … Undo Delete : Cannot fulfill fault
- From: Jerry Krinock <email@hidden>
- Date: Thu, 29 Sep 2011 16:50:46 -0700
On 2011 Sep 29, at 11:20, Quincey Morris wrote:
> I'm pretty sure … that Core Data undo *doesn't* work across 'save:' boundaries. … If I'm right, you should be clearing the undo stack at a save, at least if there are deleted objects in the picture.
> Alternately, I'm completely wrong.
I think you're correct, but not directly. The -[NSManagedObjectContext undo] method whose documentation you read so deftly is not involved. It does not get invoked when user clicks Edit ▸ Undo in a Cocoa application.
* * *
Like any normal app, my app's Edit ▸ Undo menu item targets First Responder. A careful reading of the documentation [1] reveals that the message is targeted to -[NSDocument undo]. There is no indication that NSPersistentDocument overrides -undo, either in the header nor the Class Reference document. Therefore, I don't care what -[NSManagedObjectContext undo] says because I'm not invoking it.
The debugger tells me the same thing. A breakpoint in -[NSManagedObjectContext undo] does *not* break when user clicks Undo [2]. Apparently, -[NSManagedObjectContext undo] is only used in contexts that are not associated with a document, like a detail sheet or in a non-document-based app.
* * *
But since NSUndoManager is just a glorified container for invocations, and since the heavy lifting is done by -[NSManagedObjectContext _undoUpdates], it makes sense that the same limitation would apply, but was never documented.
Clearing the undo stack upon save is obviously not acceptable – I've never seen any app do that. Clearing it only "if there are deleted objects in the picture" is not acceptable either because that situation is when the user wants it most. Apple's NSPersistentDocument tutorial sample (DepartmentAndEmployees) does not do that. My app opts in to Autosave In Place. If I cleared the undo stack upon save, Undo would never be available for more than 15 seconds.
Jerry
[1] There are only two -undo methods in Cocoa: in NSUndoManager and in NSManagedObjectContext, and no instance of either is in the responder chain. The paradox is explained in this document:
Undo Architecture ▸ Using Undo in AppKit-Based Applications ▸ Undo and the Responder Chain
"NSResponder declares the undoManager method for most objects that inherit from it (namely, windows and views). When the first responder of an application receives an undo or redo message, NSResponder goes up the responder chain looking for a next responder that returns anNSUndoManager object from undoManager. Any returned undo manager is used for the undo or redo operation."
NSDocument is in the Responder Chain and implements -undoManager; thus, NSUndoManager gets the -undo message.
[2] Astute readers of this thread will say "Aha, that's because you're using GCUndoManager instead of NSUndoManager". Yes, but for this test I switched a #if to use NSUndoManager. While I was there, I confirmed that I still get about the same 59% failure rate in my corner case, whether I'm using NSUndoManager or GCUndoManager.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden