Reputation: 5119
I have a class (call it classA) that contains a property named info
(a model class, containing lots of info), wich in turn contains a property named name
(a string). I want another class (classB) to receive a KVO notification when the string name
changes in classA.
This is what I'm doing now on classB:
[classA addObserver: self forKeyPath: @"info.name" options: 0 context: nil];
There are two ways the value name
changes on classA: when it is set directly like classA.info.name = ...
and when info
is set like classA.info = ...
When name
is changed directly KVO works perfectly. However, when the info
property is set and name
changes indirectly, I get this error:
Cannot update for observer <classB> for the key path "info.name" from <classA>, most likely because the value for the key "info" has changed without an appropriate KVO notification being sent. Check the KVO-compliance of the classA class.
What should I change on classA to make this work?
Upvotes: 2
Views: 889
Reputation: 652
The cause of this issue comes from the fact that you are implementing the setter -setInfo:
for info and calling willChangeValueForKey:
| didChangeValueForKey:
inside it.
I've seen many instances in which it is believed that the will|didChange...
calls need to be implemented for the KVO notification to be fired. This is true only when the setter is not explicitly called. When you do call the setter, the KVO mechanism takes care of firing the notification.
Most of the times leaving these calls in the setter is harmless and just causes extra notifications, but as seen in this case, it does cause a problem when updating a keypath -- as opposed to a key.
In short, if you do implement a setter, do not call will|didChangeValueForKey:
inside of it.
Upvotes: 4
Reputation: 33146
Options cannot be 0, I think.
Its an old API, back before Apple got diligent about API design, and you have to give it something.
Upvotes: -1