KVC与KVO

作者: ForzaJuven | 来源:发表于2018-02-27 11:21 被阅读5次

转载 原文更详细 KVC和KVO

一、KVC

KVC key-value-coding即键值编码,通常用于对某一个对象的属性进行赋值。且可以对私有属性进行赋值
基本用法如下

  [Person setValue:@"张三" forKey:@"name"];
  [Person setValue:@20 forKey:@"age"];

用此方法如果Person中有一个属性Dog,Dog又有自己的一个属性dogname,那么要对那么dogname进行赋值时[Person setValue:@"littleblack" forKey@"Dog.dogname"]会报错。此时应该使用forKeyPath方法:

  [Person setValue@"littleblack" forKeyPath:@"Dog.dogname"];

所以使用KVC时最好使用forKeyPath方法;
KVC除了访问私有变量这个用处外,还可以用于字典转模型.在person类对外提供一个接口,将转模型的工作放在模型中进行

  - (instancetype)initWithDict:(NSDictionary *)dict
  {

     if (self = [super init]) {
    //普通方法
    //self.name = dict[@"name"];
    //self.age = dict[@20];

    //KVC  缺点:字典中的键值对必须与模型中的键值对完全对应,否则程序会崩溃
           [self setValuesForKeysWithDictionary:dict];
      }
      returnself;
  }

外面可以直接将字典传入,和平常转模型相比,kvc更加方便,减少了代码量。

  NSDictionary*PersonDict = @{@"name":@"李四",@"age":@"18"};
  Person *p2 = [Person  personWithDict:PersonDict];
  NSLog(@"name = %@,age =%ld",p2.name,p2.age);

总结:
1.KVC一般用于对私用变量进行取值和赋值
2.KVC还可用于字典转模型,但是无法处理复杂的字典,且字典中的键值对必须与模型中的键值对完全对应,否则程序会崩溃

二、KVO

KVO即key-value-observing,利用一个key来找到某个属性并监听其值的改变。其实这也是一种典型的观察者模式。
1.添加观察者
2.在观察者中实现监听方法observeValueForKeyPath: ofObject: change: context:(通过查阅文档可以知道,绝大多数对象都有这个方法,因为这个方法属于NSObject)
3.移除观察者

具体代码:

 /*
     NSKeyValueObservingOptionNew =
0x01, 新值
     NSKeyValueObservingOptionOld =
0x02, 旧值
     */
// 利用KVO监听p对象name 属性值的改变
    Person *p = [[XMGPerson alloc] init];
    p.name = @"jack";
    
   /* 对象p添加一个观察者(监听器)
     Observer:观察者(监听器)
     KeyPath:属性名(需要监听哪个属性)
     */
    [p addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew  | NSKeyValueObservingOptionOld context:@"123"];
    
 /**
 *  利用KVO 监听到对象属性值改变后,就会调用这个方法
 *
 *  @param keyPath 哪一个属性被改了
 *  @param object  哪一个对象的属性被改了
 *  @param change  改成什么样了
 */
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    // NSKeyValueChangeNewKey == @"new"
    NSString *new = change[NSKeyValueChangeNewKey];
    // NSKeyValueChangeOldKey == @"old"
    NSString *old = change[NSKeyValueChangeOldKey];
    
    NSLog(@"%@-%@",new,old);
}

最后不要忘记,和通知一样,要在dealloc方法里面移除监听

- (void)dealloc
{

    [a removeObserver:bforKeyPath:@"name"];

}

相关文章

网友评论

      本文标题:KVC与KVO

      本文链接:https://www.haomeiwen.com/subject/eqqcxftx.html