码迷,mamicode.com
首页 > 其他好文 > 详细

KVC和KVO

时间:2015-11-26 21:21:02      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:

KVC是KeyValue Coding的简称,它是一种可以直接通过字符串的名字(key)来访问类属性的机制。而不是通过调用Setter、Getter方法访问

具体的例子:

1.创建一个people类,继承与NSObject

   @interface People : NSObject
   @property(nonatomic,copy)NSString *name;//people的属性
   @end

 当我们在类外访问的时候,可以通过打点调用属性

    People *p=[People new];//创建一个people
    p.name=@"李四";

也可以通过kvc的方式来调用

    People *people=[People new];
    [people setValue:@"张三" forKey:@"name"];
    NSLog(@"%@",people.name);//张三
    NSString *name=[people valueForKey:@"name"];
    NSLog(@"%@",name);
你或许说了,打点调用不是可以更加方便吗?可以kvo有一个打点调用不能实现的方法:例如

@interface People : NSObject
   {

           NSString *_name;

   }
   @end

_name是people类的全局变量,这样我们就不能进行打点调用了,这时候kvc就派上用场了

  People *people=[People new];
    [people setValue:@"张三" forKey:@"name"];
    NSLog(@"%@",people.name);//张三
    NSString *name=[people valueForKey:@"name"];//得到值
    NSLog(@"%@",name);//张三

你会发现程序居然没有报错,而且执行成功了

 

@interface People : NSObject
   {

 

           NSString *name;

 

   }
   @end

和_name同理

但是我们调用一个不存在的key时,程序就会崩溃

比如我们在程序外调用 [people setValue:@"张三" forKey:@"name1"];

Terminating app due to uncaught exception ‘NSUnknownKeyException‘, reason: ‘[<People 0x106f14270> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key name1.‘ 原因就是因为没有name1这个key值

结果和上面一样:不管结果如果,你都会发先系统调用了属性的get方法,所以总结如下首先会调用set(get)方法如果set(get)方法不存在,会找到_key当_key不存在时,会找到key当key不存在时,会crash。

2.kvc可以根据路径值访问属性和对属性赋值,例如

我们有一个car类,有一个people类

@interface People : NSObject

@property (nonatomic,strong) NSString *name;
@property (nonatomic,strong) NSNumber *age;

@property (nonatomic,strong) Car *car;
@end

 

@interface Car : NSObject
@property (nonatomic,strong) NSString *name;
@property (nonatomic,strong) UIColor *bgColor;
@end

类外调用:

 People *people = [People new];

 [people setValue:@"SUV" forKeyPath:@"car.name"];

NSString *carName=[people valueForKey:@"car.name"];//suv

3.可以通过字典对属性赋值:

例如:

@interface People : NSObject

@property (nonatomic,strong) NSString *name;
@property (nonatomic,strong) NSNumber *age;

@end

 

 NSDictionary *dict = @{@"name": @"张三",@"age":@12}

 People *people = [People new];
  [people setValuesForKeysWithDictionary:dict];

NSLog(@"%@  %d",people.name,people.age);//张三   12

 

注意事项:如果字典中的键值有id之类的xcode保留值程序就会崩溃,基本数据类行也不识别,解决方法:

//kvc崩溃的话写以下方法
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
    if ([key isEqualToString:@"id"]) {//这里的id指的是oc里面的保留字
        self.pID = value;
    }else if ([key isEqualToString:@"pSex"])
    {

//@property (nonatomic,assign) BOOL sex;
        self.sex = [value boolValue];//把对象的值改为基本的数据类型
    }

    NSLog(@"%@ %@",value,key);
}

 kvo:全称是Key-value observing,翻译成键值观察。提供了一种当其它对象属性被修改的时候能通知当前对象的机制。再MVC大行其道的Cocoa中,KVO机制很适合实现model和controller类之间的通讯。

不多说:举例说明

创建一个people类


@interface People : NSObject
@property (nonatomic,strong) NSString *name;
@end

 

给一个person对象添加观察者

 [_people addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:@"hello"];//NSKeyValueObservingOptionOld,获得旧的值 NSKeyValueObservingOptionNew:获得新的值 

假如我们改变people的name属性,就会触发事件

/*

此方法必须实现,不实现的话系统回报/*
reason: ‘<ViewController: 0x8e06540>: An -observeValueForKeyPath:ofObject:change:context: message was received but not handled.
错误

*/

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
/*
 keyPath:观察的路径
 object:被观察者
 change:改变的值
 context:对应添加时的context
 */
    NSLog(@"%s",__FUNCTION__);
}

 

 

 
 

KVC和KVO

标签:

原文地址:http://www.cnblogs.com/hualuoshuijia/p/4998846.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!