By A Beginner

Every Expert Was Once A Beginner

KVO In Objective – C — June 17, 2015

KVO In Objective – C

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
KVC in Objective-C — April 29, 2015

KVC in Objective-C

 What is KVC?

KVC- Key Value Coding in Objective-C provides a mechanism for accessing the object properties indirectly. KVC makes use of strings to identify the objects properties ,rather than using the accessor methods or accessing them directly through instance variables.

KVC is the core technology of the binding technologies used by the controller layer (MVC), also a key mechanism behind the Core Data. By using KVC we can make the application scriptable, also using the KVC methods can simplify the applications code.

What are Keys and Key Paths?

Key is a string that identifies a specific property of  an object. Typically, a key corresponds to the name of an accessor method or instance variable in the receiving object.

Eg: For a "Person Object" the keys would be firstName,lastName,emailId,address,empId. and so on..

Key Path is string of dot separated keys that is used to specify a sequence of object properties to traverse. The property of the first key in the sequence is relative to the receiver, and subsequent key is evaluated relative to the value of the previous property.

Eg: In case of the person object again the key path 'address.street' would get the value of the address property of the receiving 'person' object , and then determine the 'street' property relative to the 'address' object.

How to get attribute values using Key – Value Coding?

We can easily get the attribute values using the method, ‘valueForKey: ‘ which return the value for the specified key, relative to the receiver. If there is no accessor or instance variable for the specified key, then the receiver sends the message valueForUndefinedKey:  to itself . The default implementation of this method raises an exception NSUndefinedKeyException; The sub classes can override this behavior.

Eg: NSString *fName = [person valueForKey:@"firstName"];
Here the string fName holds the value for the property 'firstName' of the object 'person'.

How to set attribute values using Key – Value Coding?

The method setValue:forKey: sets the value of the specified key, relative to the receiver, to the provided value.If the specified key does not exist, the receiver is sent a setValue: forUndefinedKey: message. The default implementation of this method raises an NSUndefinedKeyException ; however,subclasses can override this method to handle the request in a custom manner.

The method setValue:forKeyPath: behaves in a similar fashion, but it is able to handle a key path
as well as a single key.The setValuesForKeysWithDictionary: sets the properties of the receiver with the values in the specified dictionary, using the dictionary keys to identify the properties. The default implementation invokes setValue:forKey: for each key-value pair, substituting nil for NSNull objects as required.

One additional issue that you should consider is what happens when an attempt is made to set a non-object property to a nil value. In this case, the receiver sends itself a setNilValueForKey: message. The default implementation of setNilValueForKey: raises an NSInvalidArgumentException . Your application can override this method to substitute a default value or a marker value, and then invoke setValue:forKey: with the new value

Get Sample XCode Project showing use of KVC Here!

To know more on KVC refer:

1.Key Value Coding Programming Guide by apple.

2.Understanding Key-Value Observing and Coding