KVO的学习

KVO (Key Value Observing)

Kvo是Cocoa的一个重要机制,当指定的对象的属性被修改后,则观察者就会接收到对象有变动通知。

1 注册:
-(void)addObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context

keyPath就是要观察的属性值,options给你观察键值变化的选择,而context方便传输你需要的数据(注意这是一个void*型)

[self.view addObserver:self
            forKeyPath:@"self.frame"
               options:NSKeyValueObservingOptionNew
               context:nil];


2 实现变化方法:
-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context

change里存储了一些变化的数据,比如变化前的数据,变化后的数据;如果注册时context不为空,这里context就能接收到。

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context {
  if([keyPath isEqualToString:@"self.frame"]) {
    label.text = model.value;

    ......

  }
}


3 注销

- (void)removeObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath


在使用ARC时注销的时机仍然可以使用-dealloc事件,只是不需要调用[super dealloc];

原文见:http://stackoverflow.com/questions/6959896/kvo-and-arc-how-to-removeobserver


KVC (Key Value Coding) 文档有很多这里不写了


KVO的原理:

首先参考http://blog.csdn.net/iunion/article/details/46889641介绍Objective-C类和元类的文章

isa指针指向的其实是类的元类,如果之前的类名为:Person,那么被runtime更改以后的类名会变成:NSKVONotifying_Person。
新的NSKVONotifying_Person类会重写以下方法:
增加了监听的属性对应的set方法,class,dealloc,_isKVOA。
①class
重写class方法是为了我们调用它的时候返回跟重写继承类之前同样的内容。
打印如下内容:
[java]  view plain copy
  1. NSLog(@"self->isa:%@",self->isa);  
  2. NSLog(@"self class:%@",[self class]);  
在建立KVO监听前,打印结果为:
[java]  view plain copy
  1. self->isa:Person  
  2. self class:Person  
在建立KVO监听之后,打印结果为:
[java]  view plain copy
  1. self->isa:NSKVONotifying_Person  
  2. self class:Person  
这也是isa指针和class方法的一个区别,大家使用的时候注意。
②重写set方法
新类会重写对应的set方法,是为了在set方法中增加另外两个方法的调用:
[java]  view plain copy
  1. - (void)willChangeValueForKey:(NSString *)key  
  2. - (void)didChangeValueForKey:(NSString *)key  
其中,didChangeValueForKey:方法负责调用:
[java]  view plain copy
  1. - (void)observeValueForKeyPath:(NSString *)keyPath  
  2.                       ofObject:(id)object  
  3.                         change:(NSDictionary *)change  
  4.                        context:(void *)context  
方法, 这就是KVO实现的原理了!
如果没有任何的访问器方法,-setValue:forKey方法会直接调用:
[java]  view plain copy
  1. - (void)willChangeValueForKey:(NSString *)key  
  2. - (void)didChangeValueForKey:(NSString *)key  
如果在没有使用键值编码且没有使用适当命名的访问起方法的时候,我们只需要显示调用上述两个方法,同样可以使用KVO!
- (void)setFreshHeaderView:(RefreshTableHeaderView *)headerView
{
    if (headerView != self.freshHeaderView)
    {
        if (self.freshHeaderView.superview)
        {
            [self.freshHeaderView removeFromSuperview];
        }
        
        [self addSubview:headerView];
        
        // KVO
        [self willChangeValueForKey:@"freshHeaderView"];
        objc_setAssociatedObject(self, &FRESH_HEADER_VIEW_KEY, headerView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        [self didChangeValueForKey:@"freshHeaderView"];
    }
}







  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值