这篇主要从使用上讲解一下KVO
其实如果要用KVO必须先理解KVC,KVC就是键值编码
举个例子:
我们定义一个类,person
@interface Person : NSObject
{
NSString * name;
}
@property(nonatomic, retain)NSString * name;
@end
@implementation Person
@synthesize name;
@end
那么最简单的访问该类属性name的方法,是什么,很简单
无论附值还是访问,我们都采用person.name 访问
Person * person = [[Person alloc] init];
person.name = @"123";
NSLog(@"person %@",person.name);
那么还有其他方式附值还是访问,答案是肯定的
看对他改动:
@interface Person : NSObject
{
@public
NSString * name;
}
//@property(nonatomic, retain)NSString * name;
@end
Person * person = [[Person alloc] init];
person->name = @"123";
NSLog(@"%@",person->name);
此时我将变量公布出来,所以可以采用指针访问,
那么,我们看看KVC访问吧
@interface Person : NSObject
{
@private
NSString * name;
}
Person * person = [[Person alloc] init];
[person setValue:@"123" forKey:@"name"];
NSLog(@"%@",[person valueForKey:@"name"]);
KVC包括了附值和访问,就算声明成类的是有变量,也无法阻止对于变量的访问和附值,可以看出对于KVC来说已经不存在私有变量一说了,都可以用键访问。
原理,就摘抄一下,
KVC运用了一个isa- swizzling技术。isa-swizzling就是类型混合指针机制。KVC主要通过isa- swizzling,来实现其内部查找定位的。
isa指针,如其名称所指,(就是is a kind of的意思),指向维护分发表的对象的类。该分发表实际上包含了指向实现类中的方法的指针,和其它数据。
比如说如下的一行KVC的代码:
[site setValue:@"sitename" forKey:@"name"];
就会被编译器处理成:
SEL sel = sel_get_uid ("setValue:forKey:");
IMP method = objc_msg_lookup (site->isa,sel);
method(site, sel, @"sitename", @"name");
首先介绍两个基本概念:
(1)SEL数据类型:它是编译器运行Objective-C里的方法的环境参数。
(2)IMP数据 类型:他其实就是一个编译器内部实现时候的函数指针。当Objective-C编译器去处理实现一个方法的时候,就会指向一个IMP对象,这个对象是C语言表述的类型(事实上,在Objective-C的编译器处理的时候,基本上都是C语言的)。
这下KVC内部的实现就很清楚的清楚了:一个对象在调用setValue的时候,
(1)首先根据方法名找到运行方法的时候所需要的环境参 数。
(2)他会从自己isa指针结合环境参数,找到具体的方法实现的接口。
(3)再直接查找得来的具体的方法实现。
Person * person = [[Person alloc] init];
person.name = @"123";
[person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL];
person.name = @"234";
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"name"]) {
NSLog(@"old: %@ new:%@",[change objectForKey:@"old"],[change objectForKey:@"new"]);
}
}
2014-03-26 10:57:29.765 KVCdemo[32716:a0b] old: 123 new:234
好了,这里基本就明白如何使用了,对于观察以及及时刷新界面是很强大的哦~~