【一】KVC键值编码
KVC全称Key Value Coding
KVC由NSKeyValueCoding协议支持
用来给对象中的属性进行赋值
几个重要方法:
FKBook *book = [[FKBook alloc] init];
[book setValue:@"iOS" forKey:@"name"]; // 赋值
NSString name = [book valueForKey:@"name"]; // 获取值
// 下面三个方法都是防止异常情况发生
// 处理未定义的key
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
}
- (id)valueForUndefinedKey:(NSString *)key {
return key;
}
// 处理nil
- (void)setNilValueForKey:(NSString *)key {
}
// key路径问题
// 其中item是对象,name是item对象中的属性
[book setValue:@"iOS" forKeyPath:@"item.name"];
[book valueForKey:@"item.name"];
// 利用字典给对象赋值
[book setValuesForKeysWithDictionary:@{@"name":@"iOS"}];
KVC键值编码的原理
1.会先找name属性的setter和getter方法进行赋值或者获取值
2.如果没找到会寻找_name
3.如果没找到会寻找name
3.如果都没找到,会执行valueForUndefinedKey方法
【二】KVO键值监听
KVO全称Key Value Observing
由NSKeyValueObserving协议支持
用来解决模型中数据发生改变通知视图组件刷新问题
几个重要的方法:
// 增加监听器
- (void)setItem:(FKItem *)item
{
// self.item = item; 运用self.item赋值,会默认调用item的set方法,会造成循环调用错误
self->_item = item;
// 或者 _item = item;
[self.item addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:@"hello world"];
[self.item addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew context:nil];
}
// 模型中数据发生改变时,调用此方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
NSLog(@"keyPath = %@", keyPath);
NSLog(@"object = %@", object);
NSLog(@"change = %@", change);
NSLog(@"context = %@", context);
}
// 当页面销毁时移除监听器
- (void)dealloc
{
[self.item removeObserver:self forKeyPath:@"name" context:@"hello world"];
[self.item removeObserver:self forKeyPath:@"age"];
}
KVO只有调用的setter和getter方法,才会触发
KVO和iOS的消息中心(NSNotificationCenter)有些相似
NSNotificationCenter由消息中心统一发送通知,不限于监听属性的变化,使用比KVO更加灵活