LHF Objective-C语法13KVC KVO

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方法调用

相关文章

我正在用TitaniumDeveloper编写一个应用程序,它允许我使用Ja...
我的问题是当我尝试从UIWebView中调用我的AngularJS应用程序...
我想获取在我的Mac上运行的所有前台应用程序的应用程序图标....
我是一名PHP开发人员,我使用MVC模式和面向对象的代码.我真的...
OSX中的SetTimer在Windows中是否有任何等效功能?我正在使用...
我不确定引擎盖下到底发生了什么,但这是我的设置,示例代码和...