简介
KVC 英文 (Key-Value Coding) 和 (Key-Value Observing) 是 Objective-C中最强大最实用的功能之一。当使用KVO、CoreData、CocoaBindings、AppleScript(Mac 支持)时,KVC是关键技术。
通过 KVC 访问对象属性
通过字符串描述来更改对象状态,这种方式成为键值编码(KVC)。通过指定表示要访问的属性名字的字符串标识符,可以进行类的属性读取和设置。
简要来说,KVC 提供了一种在运行时而非编译时动态访问对象属性与实例变量的方式,也就是说,我们可以用字符串的内容作为属性名称或者实例变量名称进行访问。
KVC 的基本用法
键值编码(KVC)中基本调用包括setValue:forKey:和 valueForKey:两个方法:
→ setValue:forKey:方法以字符串的形式向对象发送消息,可以设置对象实例变量的值.第一个参数为要设置的值(OC 对象),第二个参数为字符串,是对象的属性名字或者实例变量名称.
→ valueForKey:方法以字符串的形式向对象发送消息,用于获取对象中实例变量的值.参数为字符串,是对象的属性名称或者实例变量名称.
KVO的实现:
1.注册成为观察者
2.观察者定义KCO回调
3.移除观察者
比如:
1.新建一个被观察的类
2.新建一个观察者的类
3.在观察者类中注册为观察者
4.然后定义KVO的回调
5.移除观察者
被观察者类.h 文件
@interface Hero : NSObject
{
NSUInteger _HP;
}
@end
观察者.h文件
#import#import "Hero.h"
@interface Observer : NSObject
@property(nonatomic,strong)Hero *hero;
//初始化函数
-(id)initWithHero:(Hero *)hero;
@end
观察者.m文件
#import "Observer.h"
@implementation Observer
-(id)initWithHero:(Hero *)hero{
if (self = [super init]) {
self.hero = hero;
// 1.注册为观察者
// (第一个参数:观察者)
// (第二个参数:观察的东西)
// (第三个参数:标示KVO希望变化如何传递给观察者,这些值可以使用"|"进行多选.)
// (第四个参数:上下文内存区.通常为"nil")
[self.hero addObserver:self forKeyPath:@"_HP" options:1 context:nil];
}
return self;
}
//定义KVO的回调
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void *)context{
NSLog(@"还剩 %@ 血,怎么办?",[change objectForKey:NSKeyValueChangeNewKey]);
}
//移除观察者
-(void)dealloc{
// 参数1:移除的观察者对象
// 参数2:观察的键路径
NSLog(@"挂了");
[self.hero removeObserver:self forKeyPath:@"_HP"];
}
@end
ViewController.m 文件
#import "ViewController.h"#import "Hero.h"
#import "Observer.h"
@interface ViewController ()
{
Hero *_hero;
Observer *_observer;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
/*
* KVO的由来:
在编程的过程中,我们经常需要半段目标是否发生变化,以便及时的做出对应的处理,此时苹果公司就提供了一种策略,即'OC运行时'提供了'KVO'技术.其中'KVO'是基于'KVC'实现
KVO的实现:
1.注册成为观察者
2.观察者定义KCO回调
3.移除观察者
*/
Hero *hero = [Hero new];
[hero setValue:@100 forKey:@"_HP"];
Observer *observer = [[Observer alloc] initWithHero:hero];
[hero setValue:@300 forKey:@"_HP"];
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(Time:) userInfo:nil repeats:YES];
_hero = hero;
_observer = observer;
}
-(void)Time:(NSTimer *)time{
NSInteger _cuiHP = [[_hero valueForKey:@"_HP"] integerValue];
_cuiHP -= 67;
if (_cuiHP <= 0) {
NSLog(@"英雄死了");
[_hero setValue:@0 forKey:@"_HP"];
[time invalidate];
}else{
[_hero setValue:@(_cuiHP) forKey:@"_HP"];
}
}
@end