Your pattern here seems backwards. Undo managers typically don't observe 
objects themselves. Model objects register reverse actions with the undo 
manager when their properties change. In your case, you might consider 
overriding -willChangeValueForKey: to register the undo action to revert the 
property to its old value.

Also, don't design for a singleton undo manager. Having multiple undo managers 
is a very useful case.

Your -registerObserver: method is kind of odd, but I understand the motivation: 
you want to keep the set of observable properties in one place. If you follow 
the above advice of making your model objects responsible for registering 
undos, then perhaps you can avoid exposing this method.

--Kyle Sluder
(Sent from the road)

On Sep 22, 2012, at 1:12 PM, Erik Stainsby <[email protected]> wrote:

> Hello again list,
> 
> I have a custom object class RSPerson with a handful of string properties. I 
> have registered a singleton undoManager to observe changes, but the change 
> dict is always coming up symmetrical. 
> 
> Edits made to the properties through UI do not appear in the change dict.
> However setting the stringValue from the UI on the custom objects' properties 
> does trigger the observer method (?!)
> 
> Some code. The observer is set on each person as the person is populated. 
> 
> RSPerson:
> 
> #import <Foundation/Foundation.h>
> @interface RSPerson : NSObject
> 
> @property (strong) IBOutlet NSString * firstName;
> @property (strong) IBOutlet NSString * lastName;
> @property (strong) IBOutlet NSString * organization;
> 
> @property (strong) IBOutlet NSUndoManager * observer;
> 
> - (void) registerObserver:(id)observer;
> 
> @end
> 
> @implementation RSPerson
> 
> - (id) init {
>    self = [super init];
>    if(self) {
> 
>    }
>    return self;
> }
> 
> - (void) registerObserver:(id)observer {
>    self.observer = observer;
>    [self addObserver:observer forKeyPath:@"firstName"      
> options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld) 
> context:NULL];
>    [self addObserver:observer forKeyPath:@"lastName"       
> options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld) 
> context:NULL];
>    [self addObserver:observer forKeyPath:@"organization"   
> options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld) 
> context:NULL];
> }
> 
> - (void) dealloc {
>    [self removeObserver:self.observer forKeyPath:@"firstName"];
>    [self removeObserver:self.observer forKeyPath:@"lastName"];
>    [self removeObserver:self.observer forKeyPath:@"organization"];
>    self.observer = nil;
> }
> 
> @end
> 
> 
> 
> RSUndoManager:
> 
> #import <Foundation/Foundation.h>
> @interface RSUndoManager : NSUndoManager
> 
> + (RSUndoManager *) sharedInstance;
> + (BOOL) sharedInstanceExists;
> 
> - (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
> change:(NSDictionary *)change context:(void *)context;
> 
> @end
> 
> @implementation RSUndoManager
> 
> static RSUndoManager * instance = nil;
> 
> + (RSUndoManager *) sharedInstance {
>    if(!instance ) {
>        instance = [[[self class] alloc] init];
>    }
>    return instance;
> }
> 
> + (BOOL) sharedInstanceExists {
>    return (nil != instance);
> }
> 
> - (id) init {
>    if(![[self class] sharedInstanceExists])
>    {
>        self = [super init];
>        if(self) {
>        }
>        return self;
>    }
>    return instance;
> }
> 
> - (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
> change:(NSDictionary *)change context:(void *)context
> {
>    NSLog(@" [%04d] %s %@: %@",__LINE__,__PRETTY_FUNCTION__, keyPath,[change 
> description]);
> 
>    if([keyPath isEqualToString:@"organization"])
>    {
>        NSString * newVal = [change valueForKey:NSKeyValueChangeNewKey];
>        NSString * oldVal = [change valueForKey:NSKeyValueChangeOldKey];
>        if(newVal != oldVal) {
>            NSLog(@" [%04d] %s %@: %@: %@",__LINE__,__PRETTY_FUNCTION__, @" 
> not equal",oldVal,newVal);
>        }
>        else {
>            NSLog(@" [%04d] %s %@: %@: %@",__LINE__,__PRETTY_FUNCTION__, @" is 
> equal",oldVal,newVal);
>        }
>    }
> }
> 
> @end
> 
> 
> The case illustrated here ought to be showing me distinct values when I enter 
> a value into my UI in the organization field. No such luck. 
> 
> Any suggestions?
> 
> 
> 
> Erik Stainsby
> [email protected]

_______________________________________________

Cocoa-dev mailing list ([email protected])

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

This email sent to [email protected]

Reply via email to