iOS KVC KVO(键值编码,键值观察者)

1.  KVC  键值编码,他的作用是 可以通过字符串来访问属性

KVO 的优点:
 
当有属性改变,KVO 会提供自动的消息通知。这样开发人员不需要自己去实现这样的方案:每次属性改变了就发送消息通知。

这是 KVO 机制提供的最大的优点。因为这个方案已经被明确定义,获得框架级支持,可以方便地采用。

开发人员不需要添加任何代码,不需要设计自己的观察者模型,直接可以在工程里使用。

其次,KVO 的架构非常的强大,可以很容易的支持多个观察者观察同一个属性,以及相关的值。



Student类

#import <Foundation/Foundation.h>

#import "Teacher.h"

@interface Student :NSObject

@property(retain,nonatomic)NSString *name;

@property(assign,nonatomic)int age;

@property(retain,nonatomic)Teacher *teacher;


//重写


//对未定义的键的取值的处理

-(id)valueForUndefinedKey:(NSString *)key;

//对未定的键的设置的处理

-(void)setValue:(id)value forUndefinedKey:(NSString *)key;


.m

#import "Student.h"


@implementation Student


-(id)valueForUndefinedKey:(NSString *)key

{

    NSLog(@"Student:该键不存在!取毛线值啊,亲");

}

-(void)setValue:(id)value forUndefinedKey:(NSString *)key

{

    NSLog(@"Student:不存在该属性啊,设置毛线啊,亲");

}

==============================================================

Teacher类

@interface Teacher :NSObject

@property(copy,nonatomic)NSString *tname;

@property(assign,nonatomic)int tage;

//对未定义的键的取值的处理

-(id)valueForUndefinedKey:(NSString *)key;

//对未定的键的设置的处理

-(void)setValue:(id)value forUndefinedKey:(NSString *)key;


.m

#import "Teacher.h"


@implementation Teacher

@synthesize tage,tname;

-(id)valueForUndefinedKey:(NSString *)key

{

    NSLog(@"Teacher:该键不存在!取毛线值啊,亲");

}

-(void)setValue:(id)value forUndefinedKey:(NSString *)key

{

    NSLog(@"Teacher:不存在该属性啊,设置毛线啊,亲");

}

-(void)dealloc

{

    [tnamerelease];

    [superdealloc];

}

@end


==============================================================

.main

注意区别  forKey  和   forKeyPath

 Student *stu = [Studentnew];

        [stusetValue:@"zhangsan"forKey:@"name"];

        //不存在属性 name1 会调用-(id)valueForUndefinedKey:(NSString *)key;

        [stu setValue:@"zhangsan"forKey:@"name1"];

        [stu setValue:[NSNumbernumberWithInt:23]forKey:@"age"];

        //不存在name1这个键  会调用重写的方法 -(void)setValue:(id)value forUndefinedKey:(NSString *)key;

       NSString *a = [stu valueForKey:@"name1"];

       NSLog(@"%@-%d",stu.name,stu.age);

       Teacher *teach = [[Teacheralloc] init];

        [stusetValue:teach forKey:@"teacher"];

        [stu setValue:@"lisi"forKeyPath:@"teacher.tname"];

        //同样可以在Teacher类里面对未定义的键的 设置和取值做处理如下不存在 tage1

        [stu setValue:[NSNumbernumberWithInt:33]forKeyPath:@"teacher.tage1"];

       NSLog(@"teacherd的值:%@-%d",teach.tname,teach.tage);

        NSLog(@"stu获取值:%@-%d",[stuvalueForKeyPath:@"teacher.tname"],[[stuvalueForKeyPath:@"teacher.tage"] intValue


结果:

2013-08-20 13:32:32.808 demo[1732:303] Student:不存在该属性啊,设置毛线啊,亲

2013-08-20 13:32:32.832 demo[1732:303] Student:该键不存在!取毛线值啊,亲

2013-08-20 13:32:32.833 demo[1732:303] zhangsan-23

2013-08-20 13:32:32.833 demo[1732:303] Teacher:不存在该属性啊,设置毛线啊,亲

2013-08-20 13:32:32.834 demo[1732:303] teacherd的值:lisi-0

2013-08-20 13:32:32.834 demo[1732:303] stu获取值:lisi-0



2.  KVO键值观察

创建一个对象(观察者)来观察另一个对象的键值变化

StudentObserver类

#import <Foundation/Foundation.h>

#import "Student.h"

@interface StudentObserver : NSObject

//观察者要关注的对象

@property(retain,nonatomic)Student *stu;

-(id)initWithStudent:(Student *)newStu;

@end

.m


#import "StudentObserver.h"


@implementation StudentObserver

-(id)initWithStudent:(Student *)newStu

{

    if (self=[super init]) {

        self.stu  = newStu;

        //为这个stu创建要观察的属性

                                                        //多个值   |   分开

        [self.stu addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];

        [self.stu addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];

        //第一个参数常为:self 接受通知的对象 即为观察者

        //第一个参数:键路劲参数 常为观察的键路劲

        //第三个参数:标识KVO希望要如何传递给观察者  多个值 | 分开

        //第四给参数一般都为nil

    }

    return self;

}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

{

    NSLog(@"属性名:%@--%@-改为-%@",keyPath,[change objectForKey:NSKeyValueChangeOldKey],[change objectForKey:NSKeyValueChangeNewKey]);

}

-(void)dealloc

{

    //除移观察者

    [self.stu removeObserver:self forKeyPath:@"name"];

    [self.stu removeObserver:self forKeyPath:@"age"];

    [super dealloc];

}


.main

        Student *stu = [Student new];

        //创建观察者来监听stu的变化

        StudentObserver *observer=[[StudentObserver alloc] initWithStudent:stu];

        [stu setValue:@"lisi" forKey:@"name"];

        [stu setValue:@"zhangsan" forKey:@"name"];

        [stu setValue:[NSNumber numberWithInt:12] forKey:@"age"];

        [stu setValue:@"lisi" forKeyPath:@"teacher.tname"];

        [stu release];

        [observer release];

结果

2013-08-20 14:44:12.236 demo[2301:303] 属性名:name--<null>-改为-lisi

2013-08-20 14:44:12.254 demo[2301:303] 属性名:name--lisi-改为-zhangsan

2013-08-20 14:44:12.255 demo[2301:303] 属性名:age--0-改为-12




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值