kVC 与 KVO初步认识

最近了解了一下KVC与KVO。之前总觉得他们有多神秘,故了解了一下。都是实用的东西。


1、KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会接收到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。这个观察者可以是被观察的对象,也就是说,自己观察自己。

方法/步骤:

1、通过addObserver: forKeyPath: options: context方法注册观察者,并制定观察的属性是什么。

2、当被观察的属性被修改后,实现回调方法 observeValueForKeyPath:ofObject:change:context

3、移除观察者


2、KVCKeyValueCoding的简称,它是一种可以直接通过字符串的名字(key)来访问类属性的机制。而不是通过调用Setter、Getter方法访问。

当使用KVO、Core Data、CocoaBindings、AppleScript(Mac支持)时,KVC是关键技术。

关键方法定义在:NSKeyValueCodingprotocol

KVC支持类对象和内建基本数据类型。

  获取值

valueForKey:,传入NSString属性的名字。

valueForKeyPath:,传入NSString属性的路径,xx.xx形式。

valueForUndefinedKey它的默认实现是抛出异常,可以重写这个函数做错误处理。

  修改值

setValue:forKey:

setValue:forKeyPath:

setValue:forUndefinedKey:

setNilValueForKey:当对非类对象属性设置nil时,调用,默认抛出异常。

  一对多关系成员的情况

mutableArrayValueForKey:有序一对多关系成员  NSArray

mutableSetValueForKey:无序一对多关系成员  NSSet


上代码:

#import "ViewController.h"


@interface BookModel :NSObject

{

    NSString *name;

    float price;

}

@end


@implementation BookModel


@end




@interfaceViewController ()

{

    BookModel *_model;

    UILabel *_label;

    UIButton *_button;

}

@end


@implementation ViewController


- (void)viewDidLoad {

    [superviewDidLoad];


    _model = [[BookModelalloc] init];

    [_modelsetValue:@"语文"forKey:@"name"];

    [_modelsetValue:@"20.0"forKey:@"price"];

    [_modeladdObserver:selfforKeyPath:@"name"options:NSKeyValueObservingOptionNewcontext:nil];

    [_modeladdObserver:selfforKeyPath:@"price"options:NSKeyValueObservingOptionNewcontext:nil];


    

    _label = [[UILabelalloc] initWithFrame:CGRectMake(100,100, 200,30)];

    _label.backgroundColor = [UIColorclearColor];

    _label.layer.borderColor = [UIColorgreenColor].CGColor;

    _label.layer.borderWidth =1.0;

    _label.layer.masksToBounds =YES;

    _label.text = [NSStringstringWithFormat:@"%@  -  %@",[_modelvalueForKey:@"name"],[_modelvalueForKey:@"price"]];

    [self.viewaddSubview:_label];

    

    _button = [UIButtonbuttonWithType:UIButtonTypeCustom];

    _button.frame =CGRectMake(100, CGRectGetMaxY(_label.frame) +30, 100, 30);

    [_buttonsetTitle:@"改变价格"forState:UIControlStateNormal];

    [_buttonsetTitleColor:[UIColorblueColor] forState:UIControlStateNormal];

    [_buttonaddTarget:selfaction:@selector(buttonAction)forControlEvents:UIControlEventTouchUpInside];

    [self.viewaddSubview:_button];


}


- (void)buttonAction

{

    [_modelsetValue:@"数学"forKey:@"name"];

    [_modelsetValue:@"30.0"forKey:@"price"];

}


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

{

    if ([keyPathisEqualToString:@"name"] || [keyPathisEqualToString:@"price"]) {

        _label.text = [NSStringstringWithFormat:@"%@  -  %@",[_modelvalueForKey:@"name"],[_modelvalueForKey:@"price"]];

        NSLog(@"书本信息变为 %@",_label.text);

    }

}


- (void)didReceiveMemoryWarning {

    [superdidReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


@end


跑一下程序看打印结果:

2014-12-18 11:45:23.549 KVODemo-1[988:48551] 书本信息变为数学  -  20

2014-12-18 11:45:23.550 KVODemo-1[988:48551] 书本信息变为数学  -  30

从打印结果可以看出,因为先对name属性做修改,所以先得到name属性修改的信息。


这只是一些皮毛,没有挖掘深的东西。。如果想看深层的东西,可以看看Foundation框架里的NSKeyValueCoding.h 和 NSKeyValueObserving.h这两个文件。






你可能感兴趣的:(KVO,KVC)