在OC中,有着很多动态的特性,今天我们着重讲讲OC中的键值编码(KVC)和键值监听(KVO)特性、
一、键值编码(KVC)
在C#中,我们可以通过反射的方式动态去读写一个对象,有时候很方便,因为可以利用字符串的方法去控制一个对象,其实在OC中,根本不需要任何操作就可以进行属性的动态读写,这个方式就是KVC。
KVC的操作方法由NSKeyValueCoding协议提供的,而NSObject就是实现了这种协议,也就是说OC中的任何对象都支持这种KVC操作,常用的操作如下:
动态设置:
1、setValue:属性值 forKey:属性名
2、setValue:属性值 forKeyPath:属性路径(用于复合路径,例如Person有个Account类型的属性,那么Person.Account就是一个复合属性)
动态读取:
1、valueForKey:属性名
2、valueForKeyPath:属性名
下面通过一个例子理解KVC
Account.h
Account.m
Person.h
Person.m
main.m
执行结果如下:
KVC应该比较简单,那到底他是如何查找一个属性进行读取的呢?假如KVC要对a进行动态读写:
1、如果是动态设置属性,优先考虑setA方法,如果没有该方法则优先搜索成员变量_a,如果仍然不存在则搜索成员变量a,如果最后还是搜索不到,就会调用这个类的setValue:forUndeinedKey:方法(注意搜索过程中不管这些方法、成员变量是私有的还是公共的都能设置)
2、如果是动态读取属性,有限考虑a方法,属性a的getter方法,如果没有搜索到则会优先搜索成员变量_a,如果还是不存在则搜索成员变量a,如果还是不存在则会调用这个类的valueforUndefinedKey:方法
二、键值监听KVO
在WPF、Silverlight中有一种双向绑定机制,当数据模型修改了之后,会立即反应到UI视图上,类似的还有前端Web的MVVM框架,例如Knockout.js。其实OC原生就已经支持这种模式,它叫做Key Value Observing(简称KVO),可以理解成观察者模式,利用它很容易实现视图组件和数据模型的分离,当数据模型的属性值变化,会触发组件的自身。在OC中要想实现KVO则要先实现NSKeyValueObServing协议,幸运的是NSObject已经实现了该协议。
在OC中使用KVO常用的方法如下:
1、注册指定Key路径的监听器: addObserver: forKeyPath: options: context:
2、删除指定Key路径的监听器:removeObserver: forKeyPath、removeObserver: forKeyPath: context:
3、回调监听: observeValueForKeyPath: ofObject: change: context:
使用步骤:
1、通过addObserver: forKeyPath: options: context:为被监听对象(它通常是数据模型)注册监听器
2、重写监听器的observeValueForKeyPath: ofObject: change: context:方法
由于我们还没接触到界面编程,那么我们继续使用上面的例子进行扩展,假如我们希望余额变动的时候,用户可以收到通知,那就是Account就作为我们的被监听对象,需要Person为它注册监听,而人员作为监听器需要重写回调监听事件,以下为模拟这个过程:
Account.h
Account.m
Person.h
Person.m
main.m
在上面的代码中,我们在给人员分配账户时给账户的balance属性添加了监听,并且在监听回调方法中输出了监听到的信息,同时在对象销毁时移除监听,这就构成了一个典型的KVO应用。