Re: Undo in tables
Re: Undo in tables
- Subject: Re: Undo in tables
- From: Bill Cheeseman <email@hidden>
- Date: Sat, 13 Apr 2002 17:23:38 -0400
on 02-04-13 1:15 PM, Brian Webster at email@hidden wrote:
>
On Saturday, April 13, 2002, at 09:14 AM, cocoa-dev-
>
email@hidden wrote:
>
>
> 2. In your discussion of create/delete methods, you mention the need to
>
> maintain a pool of deleted methods available for redo-recreate. But you
>
> don't give an example. I'm about to implement that myself, and
>
> I think your
>
> readers would like to see an example of how to do this. I know
>
> I would! --
>
> but don't write it for me, because I'll be done by the end of the day.
>
>
Now this is one aspect of undo that I've heard contradicting
>
versions of - namely, whether or not arguments are retained by
>
NSUndoManager when you register an undo. I've seen several
>
people say that they are not retained, but every test that I've
>
ever run indicates that they are retained, via -[NSInvocation
>
retainArguments]. This is confirmed, at least in my apps, by
>
running OmniObjectMeter and looking at the retain/release
>
history. Perhaps the arguments are retained when using
>
prepareWithInvocationTarget: but not
>
registerUndoWithTarget:selector:object: ?
I've been wondering about this, too, but haven't gotten around to testing
it. In other languages and frameworks, the need for a pool of deleted
objects seems clear, but as far as I can tell from the documentation,
Cocoa's undo manager should take care of this. When you record an undo
action, you record along with it the current value in question, whether it
be a C int value or an Objective-C NSNumber object, for example, as far as I
can tell. If your table's records (rows) are objects, their previous
versions should therefore be held in the undo stack (by copying, not
retaining, because the value is different, right? -- I think I read
somewhere recently that they are copied). You want to watch out for memory
issues if your records are large, but that's the price of multiple undo and
redo.
In my application, it doesn't matter. I keep the "real" array of records in
my model object, and a separate array in the table's data source object. I
do this so that the latter can be filtered to display fewer than all of the
records in the model array. So, when I "delete" a record, I just mark a
"deleted" flag in the record and leave it in the model array for the time
being, and filter it out of the data source array so it doesn't show in the
table any longer. Undo and redo then easily get the "deleted" record back
from the model array and filter it back into the data source array for
display in the table, simply by resetting the "deleted" flag. My undo
manager only has to preserve the setting of the flag, not the whole record
object. I purge the model array of items that are marked "deleted" when the
undo stack is cleared (e.g., when the document is saved).
Maintaining two separate arrays like this makes filtering really easy, and
as a side effect it keeps deleted records around for undo and redo. It uses
very little additional memory, because the records in each array share
memory -- they are the same objects. The second array is just a bunch of
pointers to objects in the first array. And this means that editing a record
in one array automatically changes the value of the same record in the other
array, with no additional code and no synchronization issues. I've been able
to put this all together with just a handful of very simple methods.
--
Bill Cheeseman - email@hidden
Quechee Software, Quechee, Vermont, USA
http://www.quecheesoftware.com
The AppleScript Sourcebook -
http://www.AppleScriptSourcebook.com
Vermont Recipes -
http://www.stepwise.com/Articles/VermontRecipes
Croquet Club of Vermont -
http://members.valley.net/croquetvermont
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.