KVC 和 KVO 的基础理解与运用

来源:互联网 发布:python游戏编程入门pdf 编辑:程序博客网 时间:2024/05/02 15:40

KVC 和 KVO 的基础理解与运用


KVC和KVO都属于键值编程而且底层实现机制都是isa-swizzing, 下面分别对二者进行以下介绍和用法

首先

KVC概述

  • KVC是Key Value Coding的简称. 它是一种通过字符串的名字 (key) 来访问类属性的机制. 而不是通过Setter, Getter访问的.
  • 关键方法定义在NSKeyValueCodingProtocol
  • KVC支持类对象和内建基本数据类型

KVC的使用

获取值- (id)valueForKey:(NSString *)key //传入属性的名字e.g:    Person *person = [[Person alloc] init];    NSString *name = [person valueForKey:@"name"];- (id)valueForKeyPath:(NSString *)keyPath //传入路径 比如: Person类中声明了一个个Job类的属性 而Job类声明了money属性, 可以通过job.money访问e.g:    Person *person = [[Person alloc] init];    NSString *money = [person valueForKey:@"job.money"];- (id)valueForUndefinedKey:(NSString *)key //默认实现是抛出异常, 可重写这个函数做错误处理
修改值- (void)setValue:(id)value forKey:(NSString *)keye.g:    Person *person = [[Person alloc] init];    [person setValue:@"LiLei" forKey:@"name"];- (void)setValue:(id)value forKeyPath:(NSString *)keyPathe.g:    Person *person = [[Person alloc] init];    [person setValue:@"1000.0" forKey:@"job.money"];- (void)setValue:(id)value forUndefinedKey:(NSString *)key

KVO概述

键值观察Key-Value-Observer就是观察者模式。

  • 观察者模式的定义:一个目标对象管理所有依赖于它的观察者对象,并在它自身的状态改变时主动通知观察者对象。这个主动通知通常是通过调用各观察者对象所提供的接口方法来实现的。观察者模式较完美地将目标对象与观察者对象解耦。
    当需要检测其他类的属性值变化,但又不想被观察的类知道,有点像FBI监视嫌疑人,这个时候就可以使用KVO了。

KVO同KVC一样都依赖于Runtime的动态机制

KVC的使用

//注册,指定被观察者的属性//keyPath就是要观察的属性值,options给你观察键值变化的选择,而context方便传输你需要的数据(注意这是一个void型)-(void)addObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context //实现回调方法//change里存储了一些变化的数据,比如变化前的数据,变化后的数据;如果注册时context不为空,这里context就能接收到。是自动调用的,只要你所监听对象的属性或者实例变量发生变化,就自动调用该函数,执行相应操作-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context //解除注册(移除)- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;

e.g:
先定义一个Person 类

//Person.h#import <Foundation/Foundation.h>@interface Person : NSObject@end
//Person.m#import "Person.h"#import "Job.h"#import <UIKit/UIKit.h>@interface Person () {    NSString *address; //地址    CGFloat   weight;  //体重}@property (nonatomic, copy)   NSString *name; //名字@property (nonatomic, assign) NSInteger age; //年龄@property (nonatomic, strong) Job *aJob; //工作@end@implementation Person@end

再定义一个 PersonObserver 类,用于观察 Person

//PersonObserver.h#import <Foundation/Foundation.h>@interface PersonObserver : NSObject@end
//PersonObserver.m#import "PersonObserver.h"@implementation PersonObserver//观察者需要实现的方法- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{    NSLog(@"old: %@", [change objectForKey:NSKeyValueChangeOldKey]);    NSLog(@"old: %@", [change objectForKey:NSKeyValueChangeNewKey]);    NSLog(@"context: %@", context);}@end

实现

- (void)viewDidLoad {    [super viewDidLoad];    Person *aPerson = [[Person alloc] init];    PersonObserver *aPersonObserver = [[PersonObserver alloc] init];    //添加观察者    //也可以观察 age. address weight    [aPerson addObserver:aPersonObserver              forKeyPath:@"name"                 options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld)                 context:@"this is a context"];    //设置key的value值,aPersonObserver接收到通知    [aPerson setValue:@"LiLei" forKey:@"name"];    NSLog(@"name: %@", [aPerson valueForKey:@"name"]);    //移除观察者    [aPerson removeObserver:aPersonObserver forKeyPath:@"name"];      // Do any additional setup after loading the view, typically from a nib.}
0 0
原创粉丝点击