KVC and KVO in iOS
1. Introduction “KVC“ and “KVO” KVC (Key-Value-Coding) and KVO are one of the most popular concept that iOS’s developers usually listen about. But for understanding their meaning and how to use them the right way is very important for whom, who want to make your code ...
1. Introduction “KVC“ and “KVO”
KVC (Key-Value-Coding) and KVO are one of the most popular concept that iOS’s developers usually listen about. But for understanding their meaning and how to use them the right way is very important for whom, who want to make your code more dynamically. At first, I want to introduce you what is KVC.
2. KVC (Key-Value-Coding)
2.1. What is KCV?
KVC is a form of coding that allows you to access an object’s properties indirectly, using strings to access them instead of the property’s accessors or instead of accessing the variables directly. It will be explained very simple by example below:
For directly access variable “name” in your class “Student” you usually call:
var myStudent = Student() myStudent.name = "OMG" let nameStudent = myStudent.name
Now, you can access this variable like this by using KVC:
myStudent.setValue("NewOMG", forKey: "name") let newName = myStudent.valueForKey("name") as! String
The question is: every your class can use KVC?
The answer is: NO. To enable such mechanism, your classes must comply to the NSKeyValueCoding informal protocol.
Luckily for you, NSObject complies with it and it also has default implementations of its methods, so most of the time you won’t need to modify anything in order to use KVC.
Just remember that, you class has to inherited from NSObject class. This is the reason of many questions why the KVO is not working !!!!
2.2 How to use KVC
2.2.1. Simple Collection Operators using KVC
For quick visible view the result of those opraters. I give an example below.
We have class Student:
class Student : NSObject { var name: String = "" var age: Int = 0 var group: String = "" var MathematicPoint : Float = 0.0 var EglishPoint : Float = 0.0 var PhysicPoint : Float = 0.0 }
And now we have an array of some objects of this class:
var arr : NSArray = [studA,studB, studC, studD,studE,studF]
@count: Returns the number of objects in the collection as an NSNumber.
@sum: Converts each object in the collection to a double, computes the sum, and returns the sum as an NSNumber.
@avg: Takes the double value of each object in the collection, and returns the average value as an NSNumber.
@max: Determines the maximum value using compare:. Objects must support comparison with one another for this to work.
@min: Same as @max, but returns the minimum value in the collection.
2.2.2 Object Operators
@unionOfObjects / @distinctUnionOfObjects: Returns an array of the objects in the property specified in the key path to the right of the operator. @distinctUnionOfObjects removes duplicates, whereas @unionOfObjects does not.
2.2.3 Sorting using KCV
For sorting an array you can write the descriptor with the key that you want to sort. Let's see the example:
3. KVO (Key-Value-Observing)
3.1 What is KVO?
KVO - the main purpose of this mechanism is observing some changes of variables. It’s easier for you to understand when you try to answer the question: ”How can you know when some variable of class is changed?”. In iOS, has a simple way, this is using KVO.
Let’s see the example: We have object studentA of class Student, now we want to inform his parents when his Mathematic point is changed. At first, we have to register observer to his parents with key is "MathematicPoint", and his parents have to turn on listener, which's called "observeValueForKeyPath". From now, every changes of his mathematic point will be informed to his parent. For more visual, please look at example.
3.2 Using KVO
3.2.1 Add observe
self here is his parents
self.studA.addObserver(self, forKeyPath: "MathematicPoint", options: NSKeyValueObservingOptions.New | NSKeyValueObservingOptions.Old, context: nil)
3.2.2 Listen the changes
Now we add listener for keypath, in this case parent will say "OMG you are so stupid" if the mathematic point is less than 5.0, otherwise they will say "Come on baby"
override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) { if keyPath == "MathematicPoint" { if self.studA.MathematicPoint < 5.0 { self.studA.resultString = "OMG you are so stupid" } else { self.studA.resultString = "Come one baby" } } }
Let's see the result when we change Mathematic point:
Important Note when using KVO:
When you add an observer to an object, don't forget to remove it before you release the object, because your object was registered to the listener list with the your keypath. So, if you don't remove it, the listener will access to 'nil' (because your object was released), and ofcouse your app will crash.
4. Conclusion
Both Key-Value Coding and Key-Value Observing are mechanisms that allow you to create more powerful, more flexible and more efficient applications. These mechanisms are not adopted by a great number of developers, and that’s a pity, because even though they look weird at the beginning, at the end it’s proved to be very easy to be handled. In this tutorial I made an effort to provide you with a detailed introduction to both the KVC and KVO concepts. What you have learnt here is good enough to let you work with them in your projects, but there is more advanced information you could look up if you want so. It would be impossible to cover everything into one tutorial, but the most you need is here. So, having this post as a guide, I hope you’ll manage to use the demonstrated techniques to your projects too, and of course, you can add the last class we created in the previous section to your programming toolbox. Happy Key-Value programming!