首页 > 代码库 > KVO机制
KVO机制
#import <Foundation/Foundation.h>
#import "Person.h"
#import "BankAccount.h"
int main(int argc, const char * argv[])
{
// 实例化一个人, 表示是这个名字叫wangdelong的人, 准备在银行开户
Person *person = [[Person alloc] init];
person.name=@"wangdelong";
// 实例化一个银行账户对象, 表示这个zhangsan在银行的开户信息
BankAccount *account = [[BankAccount alloc]initWithPerson:person];
// 第二个参数:这里表达的意思, 当accountBlance发生变化的时候(注意必须以kvc或者是set方法改变才行),要通知监听者新的数据, 和老的数据
[account addObserver:person forKeyPath:@"accountBlance" options:NSKeyValueObservingOptionPrior | NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
// 改变银行存款
[account changAccountBlance:200];
// 监听开始,有数据变化就执行,没有数据变化就等待,
[[NSRunLoop currentRunLoop] run];
}
************************************************
#import <Foundation/Foundation.h>
@interface Person : NSObject
//每个人都有一个名字
@property (nonatomic,retain) NSString *name;
@end
************************************************
#import "Person.h"
@implementation Person
//系统自带的方法------专门用于监听
//第一个参数:是监听的keyPath.
//第二个参数:临听的是哪个对象,在我们模拟的例子里, 指的Account
//第三个参数:监听的值发生的变化,会存放到这个字典里。
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"%@",change);
// 因为在监听的时候, 监听的是accountBlance值变化前后的值, 所以这里可以根据NSKeyValueChangeNewKey取出新值
// 变化后的值——————————表示变化的钱数————————花的钱
float newBlance = [[change valueForKeyPath:NSKeyValueChangeNewKey] floatValue];
// 变化前的值——————————表示原先的钱数————————以前的钱
float oldBlance = [[change valueForKeyPath:NSKeyValueChangeOldKey] floatValue];
NSLog(@"%f",newBlance);
NSLog(@"%f",oldBlance);
NSLog(@"尊敬的客户, 你当前消费了%f元, 余额是%f元",newBlance,oldBlance-newBlance);
}
************************************************
#import <Foundation/Foundation.h>
// 骗编译器,有这个类
@class Person;
@interface BankAccount : NSObject
@property (nonatomic,retain)Person *person;
//账户余额
@property (nonatomic,assign)float accountBlance;
//由于每一个银行账号,都必须与一个人关联, 所以在初始化的时候, 我们要指定一个人
-(id)initWithPerson:(Person *)person;
//每一个银行,都有权来根据实际情况, 修改账户里的钱,所以需要抽像出这个方法
-(void)changAccountBlance:(float)newValue;
@end
************************************************
#import "BankAccount.h"
@implementation BankAccount
-(id)initWithPerson:(Person *)person
{
self = [super init];
if (self) {
_person = person;
_accountBlance = 1000;
}
return self;
}
-(void)changAccountBlance:(float)newValue
{
// 对于KVO来说, 最重要的, 必须采用set 或者是kvc的方法来修改属性的值, 否则不会引起通知事件发生。
#warning 注意
// 这里用下划线是不可以的,对于kvo而言,必须采用set方法或者是kvc的方法来修改属性的值,但是这里用下划线相当于直接赋值,所以是不可以这样做的,最起码要用self的方式
// _accountBlance = newValue;
self.accountBlance = newValue;
// self.accountBlance = newValue; //采用的set 方法来修改属性的值, 所以可以引起通知事件。
// 以下, 是采用了KVC的机制, 所以也可以引起通知事件
// [self setValue:[NSNumber numberWithFloat:newValue] forKey:@"accountBlance"];
// self->_accountBlance = newValue; 采用指针的方法来修改属性, 实际上相当于直接访问的属性值, 所以,也不会引起通知事件的发生。
}
@end
************************************************