What is KVO ?(Key Value Observing)

KVO – Key Value Observing ,is the feature provided by COCOA which allows an object to register itself to be notified when another object changes the value of one of its properties. Here the controller would ask the model object for notification when the data changes , when the controller receives the notification from the model, the view is updated.

KVO simplify the process of registering for notifications ,and notifying any changes any objects that need to be told of the changes. Any property of an object can be observed , as long as that property’s name is key value coding compliant.

How to Register an Object For Change Notifications?

An object can register itself to be notified of the changes of its properties by the other object, by  telling the object to be observed the following : the object that should be notified when the property changes, the name of the property that should be observed, and the information the observer should be told about when the when change happens. Optionally , we can also include the pointer or object reference that should be passed to the method that is run when the change in the value of the property happens.

Eg: –

[aPerson addObserver:self
          forKeyPAth:@"personName"
             options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld)
             context:nil];

In the above snippet we see that the object we add an observer for the ‘personName’ property of the object ‘aPerson’ to be observed by the ‘self’ object , which is notified with the old and new values of the property ‘personName’ of the ‘aPerson’ object.

Once the object has registered itself as the observer of another object, this object recieves the message ‘observeValueForKeyPath:ofObject:change:context:‘. This message has the following parameters:

  • The key path of the property that changed -[personName]
  • The object whose property changed -[aPerson]
  • An NSDictionary that contains information about the change -[change dictionary]
  • The context variable that was passed in when addObserver:forKeyPath:options:context: was called -[nil]

The change dictionary contains the different information dependin on what options wer passed in when the observer was added.

Eg:-

  • NSKeyValueObservingOptionNew :  then the dictionary contains the NSKeyValueChangeNewKey key, whose object is the value that the property has been set to.
  •  NSKeyValueObservingOptionOld : then the dictionary contains the  NSKeyValueChangeOldKey key, which can be used to get the previous value of the property.

Eg:-

The example for how an object can handle the aPerson object changing its personName property :

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
       if ([keyPath isEqualToString:@"productName"]) {
           NSString* newPersonName = [change objectForKey:NSKeyValueChangeNewKey];
        // tell the appropriate view to update, based on the newPersonName variable.        }
}

How to Notify the Observers of the Changes?

Whenever implementing the key-value observation, the objects need to notify their observers when their properties change.

If the properties are declared using the ‘@property’ syntax and have compiler synthesize the accessor methods, then the object is automatically notify any registered observers when the setter methods are called.

If Objective-C properties syntax is not used for declaring the properties, or if you override the setter methods for a property , you need to manually notify the system of the changes that are being made.To do this, you call the willChangeValueForKey: and didChangeValueForKey: methods on the self object. This allows the key-value observing system to keep track of the previous and new values of a property.

Eg: – How to override the setter method for the personName property of aPerson object.

- (void) setPersonName:(NSString*)newPersonName {
          [self willChangeValueForKey:@"personName"];
          productName = newProductName;
          [self didChangeValueForKey:@"productName"];
}

To know more on KVO refer:

  1. Introduction to Key-Value Observing Programming Guide
  2. Understanding Key-Value Observing and Coding