#import
<Foundation/Foundation.h>
#import "FKItem.h"
@interface FKItemView : NSObject
@property(nonatomic , weak) FKItem* item;
- (void) showItemInfo;
@end
@implementation FKItemView
- (void) showItemInfo
{
NSLog(@"item物品名为%@,物品价格为:%d", self.item.name , self.item.price);
}
- (void) setItem:(FKItem*) item
{
self->_item = item;
[self.item addObserver:self forKeyPath:@"name"
options:NSKeyValueObservingOptionNew context:nil];
[self.item addObserver:self forKeyPath:@"price"
options:NSKeyValueObservingOptionNew context:nil];
}
// 重写该方法,当被监听的数据模型组件发生改变时,就会回调监听器的该方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context
{
NSLog(@"--observeValueForKeyPath方法被调用--");
NSLog(@"被修改的keyPath为:%@", keyPath);
NSLog(@"被修改的对象为:%@", object);
NSLog(@"被修改的属性值为:%@", [change objectForKey:@"new"]);
NSLog(@"被修改的上下文为:%@", context);
}
- (void) dealloc
{
[self.item removeObserver:self forKeyPath:@"name"]; // 删除监听器
[self.item removeObserver:self forKeyPath:@"price"]; // 删除监听器
}
@end
int main()
{
FKItem* item = [[FKItem alloc] init];
item.name = @"衬衫";
#import "FKItem.h"
@interface FKItemView : NSObject
@property(nonatomic , weak) FKItem* item;
- (void) showItemInfo;
@end
@implementation FKItemView
- (void) showItemInfo
{
NSLog(@"item物品名为%@,物品价格为:%d", self.item.name , self.item.price);
}
- (void) setItem:(FKItem*) item
{
self->_item = item;
[self.item addObserver:self forKeyPath:@"name"
options:NSKeyValueObservingOptionNew context:nil];
[self.item addObserver:self forKeyPath:@"price"
options:NSKeyValueObservingOptionNew context:nil];
}
// 重写该方法,当被监听的数据模型组件发生改变时,就会回调监听器的该方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context
{
NSLog(@"--observeValueForKeyPath方法被调用--");
NSLog(@"被修改的keyPath为:%@", keyPath);
NSLog(@"被修改的对象为:%@", object);
NSLog(@"被修改的属性值为:%@", [change objectForKey:@"new"]);
NSLog(@"被修改的上下文为:%@", context);
}
- (void) dealloc
{
[self.item removeObserver:self forKeyPath:@"name"]; // 删除监听器
[self.item removeObserver:self forKeyPath:@"price"]; // 删除监听器
}
@end
int main()
{
FKItem* item = [[FKItem alloc] init];
item.name = @"衬衫";
item.price
=
99;
FKItemView* itemView = [[FKItemView
alloc]
init];
itemView.item
= item;
[itemView showItemInfo];
item.name = @"短袖";
item.price = 69;
[itemView showItemInfo];
item.name = @"短袖";
item.price = 69;
}
一、编写本节代码的具体步骤:
1.可仿照第二章001节的代码编写步骤,可以把类的接口文件,类的实现文件写在main.m文件中。
2.本节代码要与第二章022节中的FKItem.m文件共同编译运行。
二、本节代码涉及到的知识点:
1.在iOS界面编程中,我们需要在数据模型组件的数据发生改变时,视图组件能动态地更新自己,及时显示更新之后的数据。
2.KVO(键值监听)是上述问题的一个优秀的解决方案。当数据模型组件的key路径对应的属性值发生改变时,
作为监听器的视图组件将会被激发,激发时就会调用observeValueForKeyPath:ofObject:change:context:方法。
3.使用KVO(键值监听)的步骤非常简单:
①为被监听的对象(通常是数据模型组件)注册监听器
②重写监听器的observeValueForKeyPath:ofObject:change:context:方法。
4.KVO(键值监听)的常用方法如下:
addObserver:forKeyPath:option:context: // 注册一个监听器用于监听指定的key路径
removeObserver:forKeyPath: // 为key路径删除指定的监听器
removeObserver:forKeyPath:context: // 为key路径删除指定的监听器,只是多了一个context参数
5.本节代码定义了一个FKItemView类,该类模拟一个视图组件。该视图组件中包含了一个FKItem类型的item属性,
该属性代表数据模型组件。而showItemInfo方法用于显示该数据模型组件的状态。