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 (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to