Object-C KVO的简单概述和示例
KVO(Key Value Observing)是Cocoa的一个重要机制,他提供了观察某一属性变化的方法,极大的简化了代码。这种观察-被观察模型适用于这样的情况,比方说根据A(数 据类)的某个属性值变化,B(view类)中的某个属性做出相应变化。对于推崇MVC的cocoa而言,kvo应用的地方非常广泛。(这样的机制听起来类 似Notification,但是notification是需要一个发送notification的对象,一般是 notificationCenter,来通知观察者。而kvo是直接通知到观察对象。)
when use KVO,it usually follows below:
1 注册:
- (void)addObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void*)context
keyPath就是要观察的属性值,options给你观察键值变化的选择,而context方便传输你需要的数据(注意这是一个void型)
2 实现变化方法:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void*)context
change里存储了一些变化的数据,比如变化前的数据,变化后的数据;如果注册时context不为空,这里context就能接收到。
是不是很简单?kvo的逻辑非常清晰,实现步骤简单。
说了这么多,大家都要跃跃欲试了吧。可是,在此之前,我们还需要了解KVC机制。看看这篇文章的使用-Object-C KVC的简单概述和示例
演示一个实例看看:
创建两个类Child和Nurse
Child.h
// // Child.h // KVODemo // // Created by Durban on 13-12-19. // Copyright (c) 2013年 WalkerFree. All rights reserved. // #import <Foundation/Foundation.h> @interface Child : NSObject @property (nonatomic,assign) NSInteger happyVal; @end
Child.m
// // Child.m // KVODemo // // Created by Durban on 13-12-19. // Copyright (c) 2013年 WalkerFree. All rights reserved. // #import "Child.h" @implementation Child -(id) init { self = [super init]; if(self != nil) { _happyVal = 100; [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES]; } return self; } -(void) timerAction:(NSTimer *)timer { self.happyVal--;//必须使用点语法 //第二种语法 // _happyVal--; // [self setValue:[NSNumber numberWithInteger:_happyVal] forKey:@"happyVal"]; } @end
Nurse.h
// // Nurse.h // KVODemo // // Created by Durban on 13-12-19. // Copyright (c) 2013年 WalkerFree. All rights reserved. // #import <Foundation/Foundation.h> @class Child; @interface Nurse : NSObject @property (nonatomic, retain) Child *child; -(id) initWithChild:(Child *)child; @end
Nurse.m
// // Nurse.m // KVODemo // // Created by Durban on 13-12-19. // Copyright (c) 2013年 WalkerFree. All rights reserved. // #import "Nurse.h" #import "Child.h" @implementation Nurse @synthesize child = _child; -(id) initWithChild:(Child *)child { self = [super init]; if(self != nil) { _child = child; [_child addObserver:self forKeyPath:@"happyVal" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:@"xx"]; } return self; } -(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { NSLog(@"change = %@",change); } @end
测试实现过程如下:
// // main.m // KVODemo // // Created by Durban on 13-12-19. // Copyright (c) 2013年 WalkerFree. All rights reserved. // #import <Foundation/Foundation.h> #import "Child.h" #import "Nurse.h" int main(int argc, const char * argv[]) { @autoreleasepool { Child *child = [[Child alloc] init]; Nurse *nurse = [[Nurse alloc] initWithChild:child]; [[NSRunLoop currentRunLoop] run]; // insert code here... NSLog(@"Hello, World!"); } return 0; }
gowhich得到的结果是:
2013-12-19 10:58:58.364 KVODemo[36662:303] change = { kind = 1; new = 99; old = 100; } 2013-12-19 10:58:59.359 KVODemo[36662:303] change = { kind = 1; new = 98; old = 99; } 2013-12-19 10:59:00.359 KVODemo[36662:303] change = { kind = 1; new = 97; old = 98; } 2013-12-19 10:59:01.358 KVODemo[36662:303] change = { kind = 1; new = 96; old = 97; } Program ended with exit code: 9
如果得到如上的结果,说明使用是正确的
参考文章:
http://blog.csdn.net/weiwangchao_/article/details/7454968
版权声明
由 durban创作并维护的 Gowhich博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证。
本文首发于 博客( https://www.gowhich.com ),版权所有,侵权必究。
本文永久链接: https://www.gowhich.com/blog/515
版权声明
由 durban创作并维护的 Gowhich博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证。
本文首发于 Gowhich博客( https://www.gowhich.com ),版权所有,侵权必究。
本文永久链接: https://www.gowhich.com/blog/515