KVO observeValueForKeyPath: not being called

I created a simple class that stores data, bound its properties to textfields in a window, and another main controller object has an instance of this class.

I used

addObserver:forKeyPath:options:context:

to register as an observer. However, my implementation of

observeValueForKeyPath:ofObject:change:context:

does not seem to get called.

I have read through the following to learn about KVC:
http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/Concept s/Compliant.html
http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueObserving/Conc epts/KVOCompliance.html
http://developer.apple.com/documentation/DeveloperTools/Conceptual/IB_UserGuide/ Introduction/Introduction.html

I would appreciate help regarding KVO, KVC, and common mistakes I may have made!

Posted on Jun 26, 2009 11:12 AM

Reply
5 replies

Jun 26, 2009 5:11 PM in response to LeadZeppelins

LeadZeppelins wrote:
I created a simple class that stores data, bound its properties to textfields ...

I'm confused about the relationship between the bindings and registering an observer. Are you adding the code you described in addition to bindings defined in IB? Can you reproduce the observer problem when there are no bindings involved? If so, I'd recommend these (mostly generic) trouble shooting steps:

1) Immediately prior to your addObserver call, log the value of the receiver as well as the four params. I would recommend NSLog() over the debugger for this step. When learning Cocoa, one of the most common mistakes is passing a message to a nil receiver, since there will be no run time warning. Also be sure addObserver isn't being passed to a second instance of your class which is not the active instance you meant to observe. Atm I don't know what happens when ofObject is nil, but that's probably self, so not a likely mistake.

2) In case you haven't already done so, copy and paste the declaration of observeValueForKeyPath directly from the KVO protocol ref. to replace that line in your implementation.

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change

Since this method is implemented in NSObject, you won't get a run time error if there's a typo in the signature of your implementation;

3) Also add NSLog() to the above to rule out any dependence on subsequent execution (e.g. don't conclude that failure to update some control means that observeValueForKeyPath hasn't run);

4) If none of the above helps, build the smallest possible test bed needed to demo the failure. If that test bed doesn't give you a clue, post it here.

Hope that helps!
- Ray

Jun 27, 2009 12:36 AM in response to LeadZeppelins

Just make the 2 commented changes and your code should work:

@implementation Controller
- (void)awakeFromNib
{
// this statement creates a new Data instance;
// aProperty in the new instance is not bound
// to the text field cell
// myData = [[Data alloc] init];
[myData addObserver:self
forKeyPath:@"aProperty"
options:(NSKeyValueObservingOptionNew
| NSKeyValueObservingOptionOld)
context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
// NSLog requires a formatting string as its first arg
// NSLog(keyPath);
NSLog(@"observeValueForKeyPath: keyPath=%@", keyPath);
NSLog(@" object=%@", object);
NSLog(@" text=%@", [object valueForKey:keyPath]);
}

- Ray

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

KVO observeValueForKeyPath: not being called

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.