Understanding KVC and KVO in Objective-C
Contents:
Description
In Cocoa, the Model-View-Controller pattern, a controller’s responsibility is to keep the view and the model synchronized. There are two parts to this: when the model object changes, the views have to be updated to reflect this change, and when the user interacts with controls, the model has to be updated accordingly.
Key-Value Observing helps us update the views to reflect changes to model objects. The controller can observe changes to those property values that the views depend on.
For more details, refer Key-Value Coding and Observing from objc.io;
KVC
Description
KVC, which means NSKeyValueCoding, is a protoco, and supplies accessors (getter and setter) for getting and setting property value. Only by using the KVC setter method to set the property value, can the sender send a message to the observer.
KVC has the following two getter methods: valueForKey:
and valueForKeyPath:
, two setter methods: setValue:forKey:
and setValue:forKeyPath:
.
Sample code
Assume that Person
class has two simple properties: name
and address
and a Person
type property spouse
. We have the following two pieces of code explaining the Key and KeyPath:
For Key:
1 2 3 4 5 6 7 8 9 10 |
|
For KeyPath:
1 2 3 4 5 6 7 8 9 10 11 |
|
Actually, [p valueForKeyPath:@"spouse.name"];
equals to [[p valueForKey:@"spouse"] valueForKey:@"name"];
.
KVO
Description
Key Value Observer (KVO) is based on KVC, and can observe the change of a property of another object.
KVO allows you to register as an observer of a given object and receive notification when specific properties on that object are changed. It’s an incredibly powerful capability, and it is built into Objective-C at its very core.
Sample code
Implement PersonWatcher
for observing a Person
instance.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
|
Remove observer
Refer here
You should stop observing the sender when observer is dealloced. If you fail to do this and then allow the observer to be deallocated, then future notifications to the observer may cause your application to crash.
So, remember to remove observers
- before observer is dealloced
- before the sender is dealloced
For #1
, just send removeObserver:forKeyPath
message to the sender in the -dealloc
function of the observer.
-dealloc
function is called even in ARC mode. In -dealloc
, just free non-object resources, or clean up tasks like removing observers. In -dealloc
under ARC mode, you can not call [super dealloc]
, as the compiller did it for you and this why there is an error if you call this manually.
Note:
-dealloc
is not called in garbage collection mode.
For #2
, the observer must know the life circle of the sender, and before the sender is freed, the observer must remove the observation from the sender.