KVC
除了setter和getter方法设置和修改对象的属性,以及简化的点语法。oc还提供了一种更为灵活的操作方式,这种方式允许以字符串形式间接操作对象的属性,全称是key value coding(简称KVC),即键值编码。
最基本的两个操作:
setValue:属性值 forKey:属性名 为指定属性赋值
valueForKey:属性名 获取指定属性的值
#import <Foundation/Foundation.h> @interface MineKvc : NSObject @property (nonatomic,copy) NSString * name ; @property (nonatomic,copy) NSString * pass ; @property (nonatomic,copy) NSDate * birth ; @end
#import <Foundation/Foundation.h> #import "MineKvc.h" int main(int argc, const char * argv[]) { MineKvc * myKvc = [[MineKvc alloc]init]; [myKvc setValue:@"Pudege" forKey:@"name"]; [myKvc setValue:@"2015" forKey:@"pass"]; [myKvc setValue:[[NSDate alloc]init] forKey:@"birth"]; NSLog(@"%@--%@--%@",[myKvc valueForKey:@"name"],[myKvc valueForKey:@"pass"],[myKvc valueForKey:@"birth"]); }
1.优先调用属性的setName:
2.如果没有setter方法,KVC会搜索_name的成员变量,无论在哪定义,KVC对_name成员变量赋值。
3.没有1和2,KVC会搜素name变量,无论在哪定义,KVC对name成员变量赋值。
4.若以上3条都没有找到,执行该对象的setValue:forUndefinedKey;
valueForKey 同上。
代码实现如下
#import <Foundation/Foundation.h> @interface MineKvc : NSObject { @package NSString * kvc ; NSString * _kvc ; } @property (nonatomic,copy) NSString * name ; @property (nonatomic,copy) NSString * pass ; @property (nonatomic,copy) NSDate * birth ; @end
@implementation MineKvc { int imkvc; }
#import <Foundation/Foundation.h> #import "MineKvc.h" int main(int argc, const char * argv[]) { MineKvc * myKvc = [[MineKvc alloc]init]; [myKvc setValue:@"Pudege" forKey:@"name"]; [myKvc setValue:@"2015" forKey:@"pass"]; [myKvc setValue:[[NSDate alloc]init] forKey:@"birth"]; NSLog(@"%@--%@--%@",[myKvc valueForKey:@"name"],[myKvc valueForKey:@"pass"],[myKvc valueForKey:@"birth"]); [myKvc setValue:@"KVC" forKey:@"kvc"]; NSLog(@"_kvc= %@",myKvc->_kvc); NSLog(@"kvc = %@",myKvc->kvc); [myKvc setValue:@"implementation" forKey:@"imkvc"]; NSLog(@"%@",[myKvc valueForKey:@"imkvc"]); }
2015-07-28 11:46:28.679 KVC[1879:63384] Pudege--2015--2015-07-28 03:46:28 +0000
2015-07-28 11:46:28.680 KVC[1879:63384] _kvc= KVC
2015-07-28 11:46:28.680 KVC[1879:63384] kvc = (null)
2015-07-28 11:46:28.680 KVC[1879:63384] 0
除了以上知识点,还要注意重写undefinedKey的两个方法,防止编译器抛出异常。若用KVC给简单数据类型如int赋值nil,需要重写setNilValueForKey:。
Key路径
对象的“复合属性”,即KVC的的Key路径。一个对象包含一个Pudge类型的pudge属性,而Pudge类型又包含name属性,那么KVC通过pudge.name这种Key路径来赋值。
setValue:forKeyPath;
valueForKeyPath;
KVO
kvo机制NSKeyValueObserving协议提供支持,NSObject遵循了该协议。常有方法:
addObserver:forKeyPath:options:context 注册一个监听器用于监听指定的key路径
removeObserver:forKeyPath: 为key路径删除指定监听器
removeObserver : forKey Path 同上,添加上下文context
重写该方法,当被监听的数据模型发生改变时候,就会回调监听器的该方法。
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context