Database Reference
In-Depth Information
8.2
Key Value Observing
Key Value Observing (KVO) is the sister API to KVC. KVO allows us to request
notifications when an attribute has changed. By observing attributes on an
object, we can react when those attributes are changed. KVO is also imple-
mented via an informal protocol on the
NSObject
, and we register and remove
observers using
-addObserver:for-KeyPath:options:context:
and
-removeObserver:forKeyPath:
.
These are the two primary methods, although there are other methods involved
in the protocol, just as with KVC.
If we wanted to observe the
name
value on a recipe, we would add ourselves
(or another object) as an observer for that value, like so:
static
NSString *kPragProgObserver = @
"PragProgObserver"
id myRecipe = ...
[myRecipe addObserver:self
forKeyPath:@
"name"
options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld)
context:kPragProgObserver];
This snippet of code adds
self
as an observer to the
myRecipe
object and requests
that when the
name
value changes to notify
self
of that change and include
both the old value and the new value in that notification. We pass along a
context so we can ensure we are acting on observations meant only for us
and that they are not accidentally intercepted.
We do this because it is possible that our code is not the only code in our
application observing a value, and this method may be called with the inten-
tion of being received by our superclass. To ensure that the notification we
receive is in fact intended for us, we check the context that is passed in. After
this code has been called, any time the
name
property is changed on
that
instance of
Recipe
, the
-observeValueForKeyPath:ofObject:change:context:
is called upon
self
. We can then handle the change notification as appropriate.
- (
void
)observeValueForKeyPath:(NSString*)keyPath
ofObject:(id)object
change:(NSDictionary*)change
context:(
void
*)context
{
if
(context != kPragProgObserver) {
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
return
;
}