ios中对KVO、KVC的一些理解
2014-07-08 14:54
169 查看
本文转自:kulo9veyouwei的专栏
Key-Value Observing (简写为KVO):当指定的对象的属性被修改了,允许对象接受到通知的机制。每次指定的被观察对象的属性被修改的时候,KVO都会自动的去通知相应的观察者,相当于设计模式中的观察者模式。
KVO的优点:
当有属性改变,KVO会提供自动的消息通知。这样的架构有很多好处。首先,开发人员不需要自己去实现这样的方案:每次属性改变了就发送消息通知。这是KVO 机制提供的最大的优点。因为这个方案已经被明确定义,获得框架级支持,可以方便地采用。开发人员不需要添加任何代码,不需要设计自己的观察者模型,直接可 以在工程里使用。其次,KVO的架构非常的强大,可以很容易的支持多个观察者观察同一个属性,以及相关的值。
下面我们写个简单的demo,如何使用KVO
首先定义一个类,声明两个属性,name跟pid;
[objc]
view plaincopy
@interface DataModel : NSObject
{
NSString *name;
NSString *pid;
}
在controller里
[objc]
view plaincopy
- (void)viewDidLoad
{
[super viewDidLoad];
dm=[[DataModel alloc] init];
[dm setValue:@"daren" forKey:@"name"];
[dm setValue:@"1" forKey:@"pid"];
//注册成为观察者 选项参数指定了发送变更通知时提供给观察者的信息。使用NSKeyValueObservingOptionOld选项可以将初始对象值以变更字典中的一个项的形式提供给观察者。指定NSKeyValueObservingOptionNew选项可以将新的值以一个项的形式添加至变更字典。
[dm addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
testLabel=[[UILabel alloc] init];
[testLabel setFrame:CGRectMake(20, 20, 100, 30)];
[testLabel setBackgroundColor:[UIColor clearColor]];
[testLabel setTintColor:[UIColor blackColor]];
[testLabel setText:[dm valueForKey:@"name"]];
[self.view addSubview:testLabel];
UIButton *testButton=[UIButton buttonWithType:UIButtonTypeRoundedRect];
[testButton setFrame:CGRectMake(20, 100, 100, 70)];
[testButton setTitle:@"测试" forState:UIControlStateNormal];
[testButton addTarget:self action:@selector(testPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:testButton];
}
-(void) testPressed:(id) sender
{
[dm setValue:@"wangzi" forKey:@"name"];
}
-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(voidvoid *)context
{
if([keyPath isEqualToString:@"name"])
{
testLabel.text = (NSString *)[dm valueForKey:@"name"];
}
}
- (void)dealloc
{
[testLabel release];
[dm removeObserver:self forKeyPath:@"name"];
[dm release];
[super dealloc];
}
上述代码中,我们设置了label的文字会随着datamodel类中的一个key的值变化而变化,这就是KVO的一个简单的运用。但KVO是基于KVC实现的,那什么又是KVC。
KVC:Key-Value Coding,直译是:键值编码。简单来讲,就是给属性设置值的;复杂来讲,根据网上的说法,KVC运用了一个isa-swizzling技术。isa-swizzling就是类型混合指针机制。KVC主要通过isa-swizzling,来实现其内部查找定位的。isa指针,如其名称所指,(就是is
a kind of的意思),指向维护分发表的对象的类。该分发表实际上包含了指向实现类中的方法的指针,和其它数据。
比如说如下的第一行KVC的代码,其实和第二行的普通代码是等效的:
[myClass setValue:@"daren" forKey:@"name"];
myClass._name = @"daren";
KVC的代码会被编译器处理成:
SEL sel = sel_get_uid ("setValue:forKey:");
IMP method = objc_msg_lookup (myClass->isa,sel);
method(site, sel, @"daren", @"name");
这下KVC内部的实现就很清楚的清楚了:一个对象在调用setValue的时候:
a. 首先根据方法名找到运行方法的时候所需要的环境参数。
b. 它会从自己isa指针结合环境参数,找到具体的方法实现的接口。
c. 再直接查找得来的具体的方法实现。
和notification的区别也是在,KVO是对象之间直接的交互,而notification需要notificationCenter来做为中间交互。
Key-Value Observing (简写为KVO):当指定的对象的属性被修改了,允许对象接受到通知的机制。每次指定的被观察对象的属性被修改的时候,KVO都会自动的去通知相应的观察者,相当于设计模式中的观察者模式。
KVO的优点:
当有属性改变,KVO会提供自动的消息通知。这样的架构有很多好处。首先,开发人员不需要自己去实现这样的方案:每次属性改变了就发送消息通知。这是KVO 机制提供的最大的优点。因为这个方案已经被明确定义,获得框架级支持,可以方便地采用。开发人员不需要添加任何代码,不需要设计自己的观察者模型,直接可 以在工程里使用。其次,KVO的架构非常的强大,可以很容易的支持多个观察者观察同一个属性,以及相关的值。
下面我们写个简单的demo,如何使用KVO
首先定义一个类,声明两个属性,name跟pid;
[objc]
view plaincopy
@interface DataModel : NSObject
{
NSString *name;
NSString *pid;
}
在controller里
[objc]
view plaincopy
- (void)viewDidLoad
{
[super viewDidLoad];
dm=[[DataModel alloc] init];
[dm setValue:@"daren" forKey:@"name"];
[dm setValue:@"1" forKey:@"pid"];
//注册成为观察者 选项参数指定了发送变更通知时提供给观察者的信息。使用NSKeyValueObservingOptionOld选项可以将初始对象值以变更字典中的一个项的形式提供给观察者。指定NSKeyValueObservingOptionNew选项可以将新的值以一个项的形式添加至变更字典。
[dm addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
testLabel=[[UILabel alloc] init];
[testLabel setFrame:CGRectMake(20, 20, 100, 30)];
[testLabel setBackgroundColor:[UIColor clearColor]];
[testLabel setTintColor:[UIColor blackColor]];
[testLabel setText:[dm valueForKey:@"name"]];
[self.view addSubview:testLabel];
UIButton *testButton=[UIButton buttonWithType:UIButtonTypeRoundedRect];
[testButton setFrame:CGRectMake(20, 100, 100, 70)];
[testButton setTitle:@"测试" forState:UIControlStateNormal];
[testButton addTarget:self action:@selector(testPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:testButton];
}
-(void) testPressed:(id) sender
{
[dm setValue:@"wangzi" forKey:@"name"];
}
-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(voidvoid *)context
{
if([keyPath isEqualToString:@"name"])
{
testLabel.text = (NSString *)[dm valueForKey:@"name"];
}
}
- (void)dealloc
{
[testLabel release];
[dm removeObserver:self forKeyPath:@"name"];
[dm release];
[super dealloc];
}
上述代码中,我们设置了label的文字会随着datamodel类中的一个key的值变化而变化,这就是KVO的一个简单的运用。但KVO是基于KVC实现的,那什么又是KVC。
KVC:Key-Value Coding,直译是:键值编码。简单来讲,就是给属性设置值的;复杂来讲,根据网上的说法,KVC运用了一个isa-swizzling技术。isa-swizzling就是类型混合指针机制。KVC主要通过isa-swizzling,来实现其内部查找定位的。isa指针,如其名称所指,(就是is
a kind of的意思),指向维护分发表的对象的类。该分发表实际上包含了指向实现类中的方法的指针,和其它数据。
比如说如下的第一行KVC的代码,其实和第二行的普通代码是等效的:
[myClass setValue:@"daren" forKey:@"name"];
myClass._name = @"daren";
KVC的代码会被编译器处理成:
SEL sel = sel_get_uid ("setValue:forKey:");
IMP method = objc_msg_lookup (myClass->isa,sel);
method(site, sel, @"daren", @"name");
这下KVC内部的实现就很清楚的清楚了:一个对象在调用setValue的时候:
a. 首先根据方法名找到运行方法的时候所需要的环境参数。
b. 它会从自己isa指针结合环境参数,找到具体的方法实现的接口。
c. 再直接查找得来的具体的方法实现。
和notification的区别也是在,KVO是对象之间直接的交互,而notification需要notificationCenter来做为中间交互。
相关文章推荐
- ios中对KVO、KVC的一些理解
- ios中对KVO、KVC的一些理解
- IOS中KVC和KVO理解
- iOS KVO的一些理解和使用
- iOS -- KVC和KVO区别与简单理解
- iOS中的KVC和KVO的理解
- iOS kvc kvo 理解,
- IOS开发中的kvo以及kvc的理解
- KVC,KVO的一些原理理解与使用介绍[续]
- iOS 理解KVO与KVC
- iOS开发-KVC和KVO的理解
- iOS_KVC 与 KVO 理解
- KVC,KVO的一些原理理解与使用介绍
- 理解KVC与KVO(键-值-编码与键-值-监看)
- KVO/KVC的理解
- KVC 与 KVO 理解
- iOS KVO & KVC
- ios中的KVC和KVO
- iOS:KVO/KVC 的概述与使用
- iOS之KVC和KVO