LHF Objective-C语法(13)KVC KVO

来源:互联网 发布:宿舍用品专卖店淘宝 编辑:程序博客网 时间:2024/06/05 14:26

1、KVC(NSKeyValueCoding)  

@interface Person : NSObject {   NSString *name;}-(NSString*) name;-(void) setName:(NSString*)name;@end//======================================@implementation Person-(NSString*) name{    return name;}-(void) setName:(NSString*)n{    name = n;}@end//======================================
Person *p = [[Person alloc] init];    //普通赋值取值    [p setName:@"Ken Tomcat"];    NSLog(@"%@",[p name]);        //NSKeyValueCoding 类似与java的反射    [p setValue:@"Kingkong" forKey:@"name"];    NSLog(@"%@",[p valueForKey:@"name"]);    //=====================================

@interface Address : NSObject {    NSString *city;}-(NSString*) city;-(void) setCity:(NSString*)city;@end//======================================@implementation Address-(NSString*) city{    return city;}-(void) setCity:(NSString*)c{    city = c;}-(NSString*) description{    NSLog(@"%@",city);}@end//======================================@interface Person : NSObject {    Address *address;}@end//======================================@implementation Person-(id) init{    if(self = [super init]){        address = [Address new];    }    return self;}@end

Person *p = [[Person alloc] init];    //NSKeyValueCoding 类似与java的反射    [p setValue:@"Jickey" forKeyPath:@"address.city"];    NSLog(@"%@",[p valueForKeyPath:@"address.city"]);        //KVC 不支持数组索引操作 myArray[2],但支持运算符@count @sum @avg @min @max    //假设Person的NSArray *school存放的是School类型,School 有学校的名字name,入学时间date,课程数目lessons    //[person valueForKeyPath:@"schools.@cout"];可以计算数组有多少个学校    //[person valueForKeyPath:@"schools.@sum.lessons"]可以计数这个人读过所有学校课程总数

2、KVO (NSKeyValueObserving)是NSObject的category,KVO基于KVC实现,基于观察者设计模式

警察一直监视着犯人的名字是否发生变化,只要发生变化,警察就会收到通知

例1:

#import <Foundation/Foundation.h>@interface Prisoner : NSObject{    int pid;    NSString *name;}-(void) setPid:(int)pid;-(int) pid;-(void) setName:(NSString*) name;-(NSString*) name;@end//==========================#import "Prisoner.h"@implementation Prisoner-(void) setPid:(int)p{    pid = p;}-(int) pid{    return pid;}-(void) setName:(NSString*) n{    [n retain];    [name release];    name = n;}-(NSString*) name{    return name;}-(void)dealloc{    [name release];    [super dealloc];}@end
#import <Foundation/Foundation.h>@interface Police : NSObject@end//================================#import "Police.h"@implementation Police//接受通知的方法,继承自NSObject//第一个参数是你监视的对象上的属性,第二个参数是你监视的对象,第三个参数存放了你监视的属性的值,最后一个参数我们传递nil-(void) observeValueForKeyPath:(NSString *)aPath ofObject:(id)anObject change:(NSDictionary *)aChange context:(void *)aContext{    if([aPath isEqualToString:@"name"]){        NSLog(@"Police : %@",[aChange objectForKey:@"old"]);        NSLog(@"Police : %@",[aChange objectForKey:@"new"]);    }}@end
解释:因为main中我们监听name的新旧两个值,所以aChange这个字典对象就存放了@“old” @“new”两个key-value对
Prisoner *prisoner = [[Prisoner alloc] init];    Police *police = [[Police alloc] init];        [prisoner addObserver:police forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];    [prisoner setName:@"Tom"];    [prisoner removeObserver:police forKeyPath:@"name"];    [prisoner setName:@"Ken"];    [prisoner release];    [police release];

[prisoner addObserver:police forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];

//为犯人添加观察者警察,警察关注着犯人的name是否发生变化,如果发生变化,就立即通知警察,也就是调用Police中的observeValueForKeyPath方法

//换句话说就是警察对犯人的名字感兴趣,他订阅了对犯人的名字变化的始建,这个事件只要发生了,警察就会受到通知

addObserver的调用者是要被监视的对象,第一个参数是谁要监视它,第二个参数是监视它的哪个属性的变化,第三个参数是监视属性值改变的类型,我们这里监听Old New,也就是Cocoa会吧name属性改变之前的旧值,改变之后的新值都传递到P哦里侧的处理通知的方法,最后一个参数我们传递nil

Notification是Objective-C中的另一种事件通知机制,

例2:

犯人类型同上

#import <Foundation/Foundation.h>@interface Police : NSObject-(void) handleNotification:(NSNotification *) notification;@end//===================================#import <Foundation/Foundation.h>#import "Police.h"#import "Prisoner.h"@implementation Police//v1.2-(id) init{    if(self = [super init]){        NSNotification *nc = [NSNotificationCenter defaultCenter];        [nc addObserver:self selector:@selector(handleNotification:) name:@"prisioner_name" object:nil];    }}-(void) handleNotification:(NSNotification *) n{    Prisoner *prisoner  = [n object];//获得通知中心传递事件源对象    NSLog(@"%@",[prisoner name]);}@end

解释:在init方法中,先获得通知中心,它是单例的

向通知中心把自己添加为观察者,第一个参数是观察者,也就是警察自己,第二个参数是观察事件的标识符priseoner—name,第三个参数指定handleNotification为处理通知的方法

接收通知,这个方法名任意,

//v1.2    Prisoner *prisoner = [[Prisoner alloc] init];    Police *police = [[Police alloc] init];    [prisoner setName:@"Tom"];    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];    [nc postNotificationName:@"prisoner_name" object:prisoner];    [nc removeObserver:police];    [prisoner setName:@"Ken"];    [prisoner release];    [police release];

向通知中心发送通知,告知通知中心有一个prisioner——name的事件发生了,并把自己作为事件源传递给通知中心

通知中心随后就会查到是谁监听了prisoner——name事件那?找到之后就调用观察者指定的处理方法,也就是Police中的handleNotification方法被调用

原创粉丝点击