iOS开发笔试面试- KVC/KVO简单使用

转自:http://my.oschina.net/caijunrong/blog/510701

一、对于KVC模式(Key Value Coding):

1、其实在实际开发中用得比较多得就是:接收到json数据之后,通过解析,解析成NSDictionary,然后再把字典对应的字段建立一个Model,在Model里面自定义一个类方法+(instancetype)modelWithDictionary:(NSDictionary *)keyDictionary方法中调用

[self setValuesForKeysWithDictionary:jsonObject];

从而达到我们想要的效果,将字典装成Model。

2、然后对于一些想要特殊处理的字段可以调用以下方法来进行特殊处理,比如里面有些key是字典类型,则可以通过以下方式搞定:

-(void) setValue:(id)value forKey:(NSString *)key 
{ 
  if([key isEqualToString:@"products"]) 
  { 
    for(NSMutableDictionary *productDict in value) 
    { 
      Prodcut *product = [[Product alloc] initWithDictionary:prodcutDict]; 
      [self.products addObject:product]; 
    } 
  } 
}

3、还有一种情况,就是里面的Key压根就没定义,可以通过重写以下这个方法来重新把key和value对应上号:

- (void)setValue:(id)value forUndefinedKey:(NSString *)key 
{ 
    if([key isEqualToString:@"nameXXX"]) 
        self.name = value; 
    if([key isEqualToString:@"ageXXX"]) 
        self.age = value; 
    else 
        [super setValue:value forKey:key]; 
}

二、对于KVO设计模式(KVO的简单使用):

Key Value Observing, 顾名思义就是一种observer 模式用于监听property的变化,KVO跟NSNotification有很多相似的地方, 用addObserver:forKeyPath:options:context:去start observer, 用removeObserver:forKeyPath:context去stop observer, 回调就是observeValueForKeyPath:ofObject:change:context:。

KVO 的实现也依赖于 Objective-C 强大的 Runtime 。

简单概述下 KVO 的实现:

当你观察一个对象时,一个新的类会动态被创建。这个类继承自该对象的原本的类,并重写了被观察属性的 setter 方法。自然,重写的 setter 方法会负责在调用原 setter 方法之前和之后,通知所有观察对象值的更改。最后把这个对象的 isa 指针 ( isa 指针告诉 Runtime 系统这个对象的类是什么 ) 指向这个新创建的子类,对象就神奇的变成了新创建的子类的实例。

原来,这个中间类,继承自原本的那个类。不仅如此,Apple 还重写了 -class 方法,企图欺骗我们这个类没有变,就是原本那个类。更具体的信息,去跑一下 Mike Ash 的那篇文章里的代码就能明白,这里就不再重复。

    下面是从另外一个博客搞过来的示例代码:

@interface StockData : NSObject {  
    NSString * stockName;  
    float price;  
}  
@end  
@implementation StockData  
@end
- (void)viewDidLoad  
{  
    [super viewDidLoad];  
  
    stockForKVO = [[StockData alloc] init];  
    [stockForKVO setValue:@"searph" forKey:@"stockName"];  
    [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];  
  
}
-(void) buttonAction  
{  
    [stockForKVO setValue:@"20.0" forKey:@"price"];  
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context  
{  
    if([keyPath isEqualToString:@"price"])  
    {  
        myLabel.text = [stockForKVO valueForKey:@"price"];  
    }  
}
- (void)dealloc  
{  
    [stockForKVO removeObserver:self forKeyPath:@"price"];  
}
原文地址:https://www.cnblogs.com/feiyu-mdm/p/5565530.html