KVC和KVO

KVC :Key-Value-Coding(键值编码)

一个非正式的 Protocol,提供一种机制来间接访问对象的属性

下面是使用KVC 和 不使用 KVC的代码对比

Persion *persion =  [ [Persion alloc] init ];
//不使用KVC
persion.name = @"hufeng" ;
 //使用KVC的写法
[persion  setValue:@"hufeng" forKey:@"name"];

复杂点的:我们有一个人,这个人有一个手机类,这个手机类有一个电池类 我们要获取这个电池类
不用KVC:

Person *persion =  [ [Person alloc] init ];
Phone *phone = person.phone;
Battery *battery = phone.battery;

使用KVC

Battery *battery = [person valueForKeyPath: @"phone.battery"];
//相当于
[[person valueForKey: @"phone"] valueForKey:@"battery"];

KVC可以被用到字典转模型中

- (id)initWithKVCDictionary:(NSDictionary *)KVCDic{
 
    if (self = [super init]) {

        [self setValuesForKeysWithDictionary:KVCDic];
        
    }
    return self;
}

如果key不存在会崩溃,加以下代码解决:

- (void)setValue:(id)value forUndefinedKey:(NSString *)key{

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

如果key为id,可以这样处理:

- (void)setValue:(id)value forUndefinedKey:(nonnull NSString *)key {
    if ([key isEqualToString:@"id"]) {
        self.appId = (int)value;
    }
}

KVO :Key-Value-Observing(键值观察)

提供了一种当其它对象属性被修改的时候能通知当前对象的机制。

KVO使用分三步:

     (1)注册成为观察者

     (2)观察者定义KVO的回调

     (3)移除观察者

参考网上一篇文章:

1.假设一个场景,股票的价格显示在当前屏幕上,当股票价格更改的时候,实时显示更新其价格
@interface StockData : NSObject {  
    NSString * stockName;  
    float price;  
}  
@end  
@implementation StockData  
@end 
2.定义此model为Controller的属性,实例化它,监听它的属性,并显示在当前的View里边
- (void)viewDidLoad  
{  
    [super viewDidLoad];  
  
    stockForKVO = [[StockData alloc] init];  
    [stockForKVO setValue:@"10.0" forKey:@"price"];      
    [stockForKVO addObserver:self forKeyPath:@"price" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];  
  
    myLabel = [[UILabel alloc]initWithFrame:CGRectMake(100, 100, 100, 30 )];  
    myLabel.textColor = [UIColor redColor];  
    myLabel.text = [stockForKVO valueForKey:@"price"];  
    [self.view addSubview:myLabel];  
     
    UIButton * b = [UIButton buttonWithType:UIButtonTypeRoundedRect];  
    b.frame = CGRectMake(0, 0, 100, 30);  
    [b addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];  
    [self.view addSubview:b];  
} 
3.当点击button的时候,调用buttonAction方法,修改对象的属性
-(void) buttonAction  
{  
    [stockForKVO setValue:@"20.0" forKey:@"price"];  
} 
4. 实现回调方法
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context  
{  
    if([keyPath isEqualToString:@"price"])  
    {  
        myLabel.text = [stockForKVO valueForKey:@"price"];  
    }  
}
5.增加观察与取消观察是成对出现的,所以需要在最后的时候,移除观察者
- (void)dealloc  
{  
    [super dealloc];  
    [stockForKVO removeObserver:self forKeyPath:@"price"];  
    [stockForKVO release];  
} 

你可能感兴趣的:(KVC和KVO)