KVO浅析与实例
来源:互联网 发布:二级域名解析到端口 编辑:程序博客网 时间:2024/05/29 16:38
转载请注明本文章出处:http://www.androiddev.net/
什么是KVO?
KVO是Key-Value-Observing的缩写,通过KVO这种机制对象可以通过它得到其他对象的某个属性的变更通知。这种机制在MVC模式下显得更为重要,KVO可以让视图对象经过控制器观察模型对象的变更从而做出更新等操作。
KVO这一机制是基于NSKeyValueObserving协议的,Cocoa通过这个协议为所有遵循协议的对象提供了自动观察属性变化的能力。在NSObject中已经为我们实现了这一协议,所以我们不必去实现这个协议。
下图形象的表示了KVO的一种工作流程:
为什么要使用KVO?
有的朋友可能会有疑问,为什么要使用KVO呢?KVO能实现的我使用Setter方法同样能实现啊。其实不然KVO存在还是有它的价值的,那么接下来我们细数一下KVO的独特价值吧:
1.我们创建一两个setter方法感觉没什么,但是如果要观察的属性非常多,那么还能一一重写setter方法来实现吗?想必大家心里已有了答案,但是利用KVO则能很好的解决上述问题。
2.我们自定义的类是很容易改写setter方法的,但是如果你是用一个已经编译好了的类库时要监控其中一个属性时怎么办?难道还要去重写setter方法?如果使用KVO则很轻松解决问题。
3.使用KVO能够方便的记录变化前的值和变化后的值,不适用KVO你还要自己来解决这些问题。
4.KVO让你的代码看起来更加简洁清晰易于维护。
如何使用KVO呢?
首先,你要为你想观察的对象添加一个观察者代码如下:
[object addObserver: observer forKeyPath: @"frame" options: 0 context: nil];
调用方法是:
object : 被观察对象
observer: 观察对象
forKeyPath里面带上property的name,如UIView的frame、center等等
options: 有4个值,分别是:
NSKeyValueObservingOptionNew 把更改之前的值提供给处理方法
NSKeyValueObservingOptionOld 把更改之后的值提供给处理方法
NSKeyValueObservingOptionInitial 把初始化的值提供给处理方法,一旦注册,立马就会调用一次。通常它会带有新值,而不会带有旧值。
NSKeyValueObservingOptionPrior 分2次调用。在值改变之前和值改变之后。
注:例子里的0就代表不带任何参数进去
context: 可以带入一些参数,任何类型都可以,强制转就可以。
接下来观察到值的变化后该应该调用相关的方法来处理,这个方法是:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
其中:
keyPath: 对应forKeyPath
object: 被观察的对象
change: 对应options里的NSKeyValueObservingOptionNew、NSKeyValueObservingOptionOld等
context: 对应context
实战代码
我们写一个学生类写一个pageview类来观察学生类中某些属性的变化并作出相关响应。
1
Student.h
2
#import <Foundation/Foundation.h>
3
4
@interface
Student :
NSObject
5
6
@property
(
nonatomic
)
NSString
*name;
7
8
@property
(
nonatomic
)
NSString
*courseName;
9
10
@property
(
nonatomic
)
double
age;
11
12
- (
void
)changeCourseName:(
NSString
*)newCourseName;
13
14
@end
15
16
Student.m
17
#import "Student.h"
18
19
@implementation
Student
20
21
- (
void
)changeCourseName:(
NSString
*)newCourseName{
22
_courseName = newCourseName;
23
}
24
25
@end
26
27
pageView.h
28
#import <Foundation/Foundation.h>
29
#import "Student.h"
30
31
@interface
pageView :
NSObject
32
- (
id
)init:(Student*)stu;
33
@end
34
35
pageView.m
36
#import "pageView.h"
37
38
@implementation
pageView{
39
Student *student;
40
}
41
42
- (
id
)init:(Student*)stu{
43
if
(
self
= [
super
init]){
44
student = stu;
45
[stu addObserver:
self
46
forKeyPath:
@"courseName"
47
options:
NSKeyValueObservingOptionNew
48
|
NSKeyValueObservingOptionOld
49
context:
nil
];
50
[stu addObserver:
self
51
forKeyPath:
@"age"
52
options:
NSKeyValueObservingOptionNew
53
|
NSKeyValueObservingOptionOld
54
context:
nil
];
55
}
56
return
self
;
57
}
58
59
- (
void
)dealloc{
60
[student removeObserver:
self
forKeyPath:
@"courseName"
];
61
}
62
63
- (
void
)observeValueForKeyPath:(
NSString
*)keyPath ofObject:(
id
)object change:(
NSDictionary
*)change context:(
void
*)context{
64
if
([keyPath isEqualToString:
@"courseName"
]){
65
NSLog
(
@"课程发生了改变"
);
66
NSLog
(
@"新课程是:%@ 老课程是:%@"
,[change objectForKey:
@"new"
],[change objectForKey:
@"old"
]);
67
}
else
if
([keyPath isEqualToString:
@"age"
]){
68
NSLog
(
@"课程发生了改变"
);
69
NSLog
(
@"新课程是:%@ 老课程是:%@"
,[change objectForKey:
@"new"
],[change objectForKey:
@"old"
]);
70
}
71
}
72
73
@end
74
75
main.m
76
#import <Foundation/Foundation.h>
77
#import "Student.h"
78
#import "pageView.h"
79
80
int
main(
int
argc,
const
char
* argv[])
81
{
82
83
@autoreleasepool
{
84
85
Student *student = [[Student alloc] init];
86
student.courseName =
@"math"
;
87
student.age = 10;
88
pageView *view = [[pageView alloc] init:student];
89
student.courseName =
@"ddd"
;
90
student.age = 15;
91
NSLog
(
@"%@"
,student.courseName);
92
93
}
94
return
0;
95
}
当我们观察的那个值与多个其他的值有关时我们应该重写
+ (NSSet *)keyPathsForValuesAffecting<key>方法
其中<key>是你要监听的那个值的名字如rect
+ (NSSet *)keyPathsForValuesAffectingRect
综合实战
通过滑动slider来改变相关的值,相关的只发生变化后从而改变标签的颜色。
下载地址:https://github.com/zhaishuai/KVOPractice
- kvo浅析与实例
- KVO浅析与实例
- KVO浅析与实例
- KVO浅析与实例
- kvo浅析与实例
- kvo浅析与实例
- KVO实例浅析
- KVO简单实例与细节
- AppDomain浅析与实例
- IOCP 浅析与实例
- IOCP 浅析与实例
- KVO模式浅析
- 浅析 KVO 内部实现
- KVO原理浅析
- KVO、KVC、NSNotificationCenter实例
- iOS KVO 实例
- KVO的使用实例
- Hibernate批量更新与删除实例浅析
- 硬件知识andl linux发展历史
- android之BitmapFactory.Options的使用
- MyEclipse 8.5破解
- Spring事务管理(AOP/声明式式事务管理)
- android 导入library
- KVO浅析与实例
- leetcode:First Bad Version
- 仿QQ侧滑
- remastersys用法
- 关于微信支付的error code
- 关于移位操作
- JAVA 常用API Date 类
- Excel 转sql
- NSArray和NSMutableArray的创建及常用方法