0.场景
对于一些实时性比较高的数据,我们通常的做法是获取数据、处理数据、通知更新UI。但是发现实现起来比较麻烦,但是我们希望能更加简单,只要这个数据一旦发生变化就直接更新数据,直接明了。苹果提供的KVO正好能解决这类问题,而KVO一般建立在Model与Controller之间,KVO是建立在KVC的基础上实现的。
1.简单的概念
KVC-Key-Value Coding-NSKeyValueCoding-键值编码
KVO-Key-Value Observing-NSKeyValueObserving-键值监听
2.kvc-主要方法
//Setting Values
- (void)setValue:(id)value forKey:(NSString *)key;
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
//Getting Values
- (id)valueForKey:(NSString *)key;
- (id)valueForKeyPath:(NSString *)keyPath;
3.KVO
设计思路:页面上有一个按钮与一个价格标签,按钮每点击一次,价格就会上调10块。
3.1创建model
ViewControllerModelOne.h
@interface ViewControllerModelOne : NSObject
@property(nonatomic,copy)NSString *priceValue;
@end
3.2监听数据
3.2.1注册对应key(priceValue)观察者
//初始化并设置默认值
price=@"0";
model = [[ViewControllerModelOne alloc] init];
[model setValue:price forKey:@"priceValue"];
//注册priceValue的观察者
[model addObserver:self forKeyPath:@"priceValue" options:0 context:NULL];
3.2.2移除对应Key(priceValue)观察者
- (void)dealloc{
[model removeObserver:self forKeyPath:@"priceValue"];
model=nil;
}
3.2.3重写回调函数
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if([keyPath isEqualToString:@"priceValue"]){
//更新ui
priceLabel.text = [model valueForKey:@"priceValue"];
}
}
4.KVC-KeyPath
通常我们的model也可能需要其他model的数据,比如说a用户有首b歌曲,b歌曲里面有c项歌曲信息。对于刚才的ViewControllerModelOne(b)则需要ViewControllerModelTwo(c)的信息。
4.1创建model
ViewControllerModelTwo.h
@interface ViewControllerModelTwo : NSObject
@property(nonatomic,copy)NSString *priceValue;
@end
并且在ViewControllerModelOne添加ViewControllerModelTwo作为变量
ViewControllerModelOne.h
@interface ViewControllerModelOne : NSObject
@property(nonatomic,copy)NSString *priceValue;
@property(nonatomic,strong)ViewControllerModelTwo *modelTwo;
@end
4.2设置与获取对象的对象
补充说明:
1.4.2的方法(setValue:forKey:)与3.2的方法(setValue:forKeyPath:)不一样
2.keyPath可以将多个key以点”.”的形式连接起来,比如:modelTwo.priceValue
//实例化
ViewControllerModelTwo *modelTwo=[[ViewControllerModelTwo alloc] init];
//设为model的modelTwo
[model setValue:modelTwo forKey:@"modelTwo"];
//再设置model中modelTwo的priceValue对象
[model setValue:price forKeyPath:@"modelTwo.priceValue"];
//获取model中modelTwo的priceValue对象
[model valueForKeyPath:@"modelTwo.priceValue"]
5.KVC-Collection Operators
对于a用户用多首b歌曲,我想知道b歌曲的个数可以通过运算符来计算,运算符以@开头,而官方提供的有@avg、@count、@max、@min、@sum,暂不支持自定义。
//歌曲1
ViewControllerModelOne *modelOne = [[ViewControllerModelOne alloc] init];
[modelOne setValue:@"2" forKey:@"priceValue"];
//歌曲2
ViewControllerModelOne *modelTwo = [[ViewControllerModelOne alloc] init];
[modelTwo setValue:@"4" forKey:@"priceValue"];
//通过数组形式包装
NSArray *modelArray=@[modelOne,modelTwo];
//查出对应的属性(@"@avg.priceValue"、@"@count..."、@"@max..."、@"@min..."、@"@sum..." )
NSArray *priceValueArray=[modelArray valueForKeyPath:@"@max.priceValue"];