Observing object using proxy object

305 views Asked by At

Should I be able to set up an observer on a proxy object, change what the proxy object is pointing to and still be able to observe changes on the real object?

An example might explain this best. Consider the following.

In the header:

@interface MyController : NSObject {   

  MyWidgetModel * aProxyObject;

}

In an initialization or awake from NIB method:

-(void)awakeFromNib {

 // Init the proxy object. Could be as an empty widget 

 [aProxyObject addObserver:self 
                forKeyPath:@"widgetName"
                   options:NSKeyValueObservingOptionNew 
                   context:nil];

}

Some other method that changes the object:

-(void)changeWidget:(MyWidgetModel *)aNewWidget {

  aProxyObject = aNewWidget;

}

This doesn't fire any changes in aNewWidget. However, if I move the addObserver to after the assignment as follows, it works:

-(void)changeWidget:(MyWidgetModel *)aNewWidget {

   [aProxyObject removeObserver:self forKeyPath:@"widgetName"];

   aProxyObject = aNewWidget;

   [aProxyObject addObserver:self 
                  forKeyPath:@"widgetName"
                     options:NSKeyValueObservingOptionNew 
                     context:nil];
}

I am assuming that the first case doesn't work is because the observer is observing the memory pointer of the proxy object's reference and, as there is no object at the time the proxy observer is added has nothing to observe. However, if I init a widget and observe that, then assign the proxy object aNewWidget it still doesn't observe changes unless I add the observer after the assignment (and of course creating a need to remove the observer on a change of object).

Also, what happens in this scenario if aNewWidget gets destroyed? Because the observer is on the proxy, does this negate the need to remove the observer before destroying the object? (I assume it doesn't).

Ideally I'd like to be able to set the observer on the proxy and swap in and out whatever widget reference I want to the proxy object without having to worry about adding and removing the observer unless the MyController class goes away in which case I could handle the observer removal in the dealloc.

Any help/comments/advice appreciated.

1

There are 1 answers

1
Infinite Possibilities On BEST ANSWER

The keyPath must be KVC compliant. So here's the code:

@interface MyController : NSObject {   
  MyWidgetModel * aProxyObject;
}
@property (nonatomic, retain) MyWidgetModel * aProxyObject;

Don't forget to synthetize it in the implementation file. Then use this code to add the observer:

[self addObserver:self 
            forKeyPath:@"aProxyObject"
               options:NSKeyValueObservingOptionNew 
               context:nil];

Please check my edit. I've changed the assign to retain. Maybe it is better for you. You should try to choose the best for you. I just want to say it doesn't matter in KVO.