KVC
KVC概述
KVC
即 Key-value coding
键值编码,是指iOS的开发中,可以允许开发者通过Key
名直接访问对象的属性,或者给对象的属性赋值。
KVC案例
@interface Person : NSObject@property (nonatomic,assign) int age;
@property (nonatomic,copy) NSString *name;@end
复制代码
如以上代码,我们创建了一个 Person
类,他有两个属性,分别是 age
和 name
。 然后我们将其实例化,并且赋予其姓名和年龄属性:
Person *p1 =[Person new];
p1.name = @"Kobe";
p1.age = 30;
复制代码
这是常规的赋值方式,那么KVC是如何赋值的呢?
[p1 setValue:@"Kobe" forKey:@"name"];
[p1 setValue:@"38" forKey:@"age"];
复制代码
如以上代码,通过KVC,我们可以直接使用键值对的方式对对象的属性进行赋值。
同理,获取属性也可以使用键值对的方式:
[p1 valueForKey: @"name"];
[p1 valueForKey:@"age"];
复制代码
这样即可获取对象的 name
和 age
属性。
那么给我们再设置一个 Dog
类
@interface Dog : NSObject
@property (nonatomic,copy) NSString *name;
@end
复制代码
给 Person
类增加一个 Dog
属性
@property (nonatomic,strong) Dog *dog;
复制代码
实例化 Dog
对象并初始化,然后赋值给 Person
对象
Dog *dog1 = [Dog new];
dog1.name = @"旺财";
p1.dog = dog1;
复制代码
那么如何使用KVC给获取 p1
的 dog
的 name
属性呢? 只需要嵌套一层:
// 获取
[[p1 valueForKey:@"dog"] valueForKey:@"name"];
// 设置
[[p1 valueForKey:@"dog"] setValue:@"狗狗" forKey:@"name"];
复制代码
还有一种简洁的方法就是使用以下方法
// 设置
[p1 setValue:@"狗狗" forKeyPath:@"dog.name"];
// 获取
[p1 valueForKeyPath:@"dog.name"];
复制代码
直接使用 "." 连接属性即可。
KVO
KVO 即 Key-Value Observing
是基于 KVC 的一种观察者模式,它可以通过 KVC 的方式对对象的属性观测,当 keyPath
的值变化时会发出通知。
KVO的实现方法
KVO的实现是以下三个步骤:
- 向通知中心注册观察
- 在某一时刻
keyPath
的值变化,通知中心向观察者发送消息,调用方法。 - 重写
dealloc
方法,注销观察。
KVO的案例
首先我们先创建一个类用于数值变化,这里就叫 KVOItem
类,给它添加一个 int
类型属性 number
。
@interface KVOItem : NSObject
@property (nonatomic,assign) int number;
@end
复制代码
然后创建并初始化对象,并为其添加观察:
item = [KVOItem new];
item.number = 0;
[item addObserver:self forKeyPath:@"number" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:@"KVOTEST"];
复制代码
这里观察 item
中 key
值为 number
的属性。 注册观察后,需要实现观察所调用的方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{if (context == @"KVOTEST") {NSLog(@"change from %@ to %@",[change valueForKey:@"old"],[change valueForKey:@"new"]);}
}
复制代码
然后我们使用一个 NSTimer
来重复更改 item
的 number
属性。
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:3 repeats:YES block:^(NSTimer *timer){item.number++;}];[timer fire];
复制代码
并且不要忘了在 dealloc
方法中注销观察:
-(void)dealloc{[item removeObserver:self forKeyPath:@"KVOTEST"];
}
复制代码
运行后我们可以看到在控制台打印以下消息:
change from 0 to 1
change from 1 to 2
change from 2 to 3
change from 3 to 4
复制代码