KVO && KVC

Posted Jk_Chan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了KVO && KVC相关的知识,希望对你有一定的参考价值。

KVO:

  • key-value observing
    • 当指定的对象的属性被修改后,则对象就会接受到通知。
    • 简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者。
    • 使用步骤:
      • 1.注册,指定被观察者的属性(由被观察者主动添加观察自己的观察者)
      • 2.实现回调方法
      • 3.移除观察
      • 使用范例:
        • @interface StockData : NSObject {
        • NSString * stockName;
        • float price;
        • }
        • @end
        • @implementation StockData
        • @end

        • - (void)viewDidLoad {
        • [super viewDidLoad];

        • stockForKVO = [[StockData alloc] init];
        • [stockForKVO setValue:@"searph" forKey:@"stockName"];
        • [stockForKVO setValue:@"10.0" forKey:@"price"];
        • //往StockDat对象上添加观察者
        • [stockForKVO addObserver:self forKeyPath:@"price" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];

        • myLabel = [[UILabel alloc]initWithFrame:CGRectMake(100, 100, 100, 30 )];
        • myLabel.textColor = [UIColor redColor];
        • myLabel.text = [stockForKVO valueForKey:@"price"];
        • [self.view addSubview:myLabel];

        • UIButton * b = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        • b.frame = CGRectMake(0, 0, 100, 30);
        • [b addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
        • [self.view addSubview:b];
        • }
        • -(void) buttonAction {
        • [stockForKVO setValue:@"20.0" forKey:@"price"];
        • }
        • //作为一个KVO的观察者需要实现回调
        • -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
        • if([keyPath isEqualToString:@"price"]) {
        • myLabel.text = [stockForKVO valueForKey:@"price"];
        • }
        • }
        • //最后需要移动观察者
        • - (void)dealloc {
        • [stockForKVO removeObserver:self forKeyPath:@"price"];
        • }

KVC:

  • KeyValueCoding的简称
    • 一种使用字符串标识符,间接访问对象属性的机制,而不是通过调用Setter、Getter方法访问。
    • 即使对象中的成员变量不是属性,也可以通过KVC读写成员变量值
    • 使用方法:
    • 关键方法:
      • NSKeyValueCodingprotocol
      • 获取值:
        • valueForKey:(NSString *)属性的名字
        • valueForKeyPath:(NSString *)传入属性的路径,xx.xx形式。
        • valueForUndefinedKey
        • 默认实现是抛出异常,可以重写这个函数做错误处理。
      • 修改值
        • setValue:forKey:
        • setValue:forKeyPath:
        • setValue:forUndefinedKey:
        • setNilValueForKey:
        • 当对非类对象属性设置nil时,调用,默认抛出异常。
      • 一对多关系成员的情况
        • mutableArrayValueForKey:
        • 有序一对多关系成员 NSArray
        • mutableSetValueForKey:
        • 无序一对多关系成员 NSSet
        • 示范例子:
          • Person类
          • @implementation Person
          • @synthesize name,age;//属性name 将被监视
          • -(void) changeName{
          • [email protected]"changeName directly";
          • }
          • @end
          • PersonMonitor类 监视了name属性
          • @implementation PersonMonitor
          • - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
          • if ([keyPath isEqual:@"name"]) {
          • NSLog(@"change happen, old:%@ new:%@",[change objectForKey:NSKeyValueChangeOldKey],[change objectForKey:NSKeyValueChangeNewKey]);
          • }
          • }
          • @end
          • //测试代码
          • //初始化被监视对象
          • Person *p =[[Person alloc] init];
          • //监视对象
          • PersonMonitor *pm= [[PersonMonitor alloc]init];
          • //KVO
          • [p addObserver:pm forKeyPath:@"name" options:(NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld) context:nil];
          • //测试前的数据
          • NSLog(@"p.name is %@",p.name);
          • //KVC
          • //通过setvalue 的方法,PersonMonitor的监视将被调用
          • [p setValue:@"name kvc" forKey:@"name"];
          • //查看设置后的值
          • NSLog(@"p name get by kvc is %@",[p valueForKey:@"name"]);
          • //效果和通过setValue 是一致的
          • [email protected]"name change by .name=";
          • //通过person自己的函数来更改name
          • [p changeName];
          • /*
          • 结果输出
          • 2011-07-03 16:35:57.406 Cocoa[13970:903] p.name is name
          • 2011-07-03 16:35:57.418 Cocoa[13970:903] change happen, old:name new:name kvc
          • 2011-07-03 16:35:57.420 Cocoa[13970:903] p name get by kvc is name kvc
          • 2011-07-03 16:35:57.421 Cocoa[13970:903] change happen, old:name kvc new:name change by .name=
          • 最后一次修改是直接修改 所以没法产生通知
          • */

 

以上是关于KVO && KVC的主要内容,如果未能解决你的问题,请参考以下文章

KVC & KVO

程序员面试闪充--KVC&KVO

KVC 与 KVO 理解

KVC与KVO

KVC和KVO

KVC与KVO