Re: strange NSUndoManager + KVC inconsistency.
Re: strange NSUndoManager + KVC inconsistency.
- Subject: Re: strange NSUndoManager + KVC inconsistency.
- From: Quincey Morris <email@hidden>
- Date: Tue, 3 Feb 2009 22:53:03 -0800
On Feb 3, 2009, at 20:58, email@hidden wrote:
I have a doc based project with a class that stores all of its
properties in a Mutable dictionary called : store.
this Class has wrapper methods for valueForKey: and setValue:forKey:
its been working great ! ui elements bind to it, you don't need to
declare the properties ahead of time, and you don't have to mention
the dictionary "store" in the key path, the properties are treated
as if they are of my Object. its elegant, clean, and easy to work
with.
and then I tried to add Undo support. undo refuses to accept that my
class is Key Value Coding compliant, for ANY keys in my dictionary,
populated or not. Now, remember... my UI works with this class...
array controllers, text fields, tables, everything. its only when I
try to add
this:
[[undoManager prepareWithInvocationTarget:[self store]]
setValue:randomObj forKey:key];
during the setValue:forKey: wrapper method, that I have trouble.
heres what the trouble says:
Error setting value for key path title of object <BKStore:
0x101e630> (from bound object <NSTableColumn: 0x10372e0>(null)):
[<NSUndoManager 0x1064910> setValue:forUndefinedKey:]: this class is
not key value coding-compliant for the key title.
The immediate cause of the problem is that prepareWithInvocationTarget
only works with methods that NSUndoManager does not itself implement.
If it's a method that's actually *in* NSUndoManager, it'll try to
execute it immediately. Since NSUndoManager is a subclass of NSObject,
it inherits the default implementation of setValue:forKey:. Splat.
Probably the easiest way around it is to add something like this:
- (void) undoValue: (id) object forKey: (NSString*) key {
[self setValue: object forKey: key];
}
to your class, and use this:
[[undoManager prepareWithInvocationTarget:self] undoValue:randomObj
forKey:key];
to capture your undo invocation.
Incidentally, I think your original version:
[[undoManager prepareWithInvocationTarget:[self store]]
setValue:randomObj forKey:key];
was wrong anyway, since undoing a change to the dictionary would not
generate the corresponding redo action. It ought to have been:
[[undoManager prepareWithInvocationTarget:self] setValue:randomObj
forKey:key];
(if that hadn't been wrong for the other reason).
_______________________________________________
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