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
向通知中心把自己添加为观察者,第一个参数是观察者,也就是警察自己,第二个参数是观察事件的标识符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方法被调用