iOS开发之KVO和KVC常用方法

KVC可以通过Key直接访问对象的属性,或者给对象的属性赋值。而不需要调用明确的存取方法。这样就可以在运行时动态地访问和修改对象的属性、而不是在编译时确定。
KVO则是对目标对象的某属性添加观察,当该属性发生变化时,通过触发观察者对象实现的KVO接口方法,来自动的通知观察者。

KVC

  • 全称:Key Value Coding(键值编码)
  • 本质 :
    • 通过set方法修改成员变量属性的值(和调用set方法修改值是一样的)
    • 而且可以修改私有成员变量的值(包括系统的私有成员变量)
    • 而且会自动转换类型(只用于简单的转换)
  • 赋值
1
2
3
4
// 能修改私有成员变量
- (void)setValue:(id)value forKey:(NSString *)key;
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
- (void)setValuesForKeysWithDictionary:(NSDictionary *)keyedValues;
  • 取值
1
2
3
4
// 能取得私有成员变量的值
- (id)valueForKey:(NSString *)key;
- (id)valueForKeyPath:(NSString *)keyPath;
- (NSDictionary *)dictionaryWithValuesForKeys:(NSArray *)keys;

私有属性赋值

  • 利用KVC给UIPageControl设置页码图片
1
2
[pageControl setValue:[UIImage imageNamed:@"current"] forKeyPath:@"_currentPageImage"];
[pageControl setValue:[UIImage imageNamed:@"other"] forKeyPath:@"_pageImage"];

比较实用的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    XSBook *book1 = [[XSBook alloc] init];
book1.name = @"5分钟突破iOS开发";
book1.price = 10.7;

XSBook *book2 = [[XSBook alloc] init];
book2.name = @"4分钟突破iOS开发";
book2.price = 109.7;

XSBook *book3 = [[XSBook alloc] init];
book3.name = @"1分钟突破iOS开发";
book3.price = 1580.7;

p.books = @[book1, book2, book3];

// 如果valueForKeyPath:方法的调用者是数组,那么就是去访问数组元素的属性值
// 取得books数组中所有XSBook对象的name属性值,放在一个新的数组中返回
// NSArray *names = [p valueForKeyPath:@"books.name"];
// NSArray *names = [p.books valueForKeyPath:@"name"];

不常用的方法

1
2
3
4
5
6
7
8
9
// 计算数量
NSLog(@"%@", [p.books valueForKeyPath:@"@count"]);
NSLog(@"%@", [p valueForKeyPath:@"books.@count"]);
// 计算里面最大值
NSLog(@"%@", [p.books valueForKeyPath:@"@max.price"]);
// 计算里面最小值
NSLog(@"%@", [p.books valueForKeyPath:@"@min.price"]);
// 计算里面平均值
NSLog(@"%@", [p.books valueForKeyPath:@"@avg.price"]);

KVO

  • 全称:Key Value Observing(键值监听)
  • 作用:监听模型的属性值改变
  • 步骤

    • 添加监听器

      1
      2
      3
      4
      5
      // 为对象p添加一个观察者(监听器)
      // Observer:观察者(监听器)
      // KeyPath:属性名(需要监听哪个属性)
      // 利用b对象来监听a对象name属性的改变
      [a addObserver:b forKeyPath:@"name" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:@"test"];
  • 在监听器中实现监听方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /**
    * 当利用KVO监听到某个对象的属性值发生了改变,就会自动调用这个
    *
    * @param keyPath 哪个属性被改了
    * @param object 哪个对象的属性被改了
    * @param change 改成咋样
    * @param context 当初addObserver时的context参数值
    */
    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
    NSLog(@"%@ %@ %@ %@", object, keyPath, change, context);
    }
要不要鼓励一下😘