KVO的基本使用

闲的没事干,回顾了下KVO、KVC,为了保存学习获得的东西,写了这博文。希望过往的朋友能用到。
次博文中的KVO是直接写在ViewController里面的,看起来比较简单易懂。
一、Key Value Observing
Key Value Observing, 顾名思义就是一种observer 模式用于监听property的变化,KVO跟NSNotification有很多相似的地方, 用addObserver:forKeyPath:options:context:去start observer, 用removeObserver:forKeyPath:context去stop observer, 回调就是observeValueForKeyPath:ofObject:change:context:。
咱们先看看代码是怎么写的吧。并且把它两种使用方式做一下对比。

1、新建一个继承与NSObject的类Product。

#import <Foundation/Foundation.h>
@interface Product : NSObject

{
    NSString *object;//这个是用于KVO中的Key,当你设置的key在这里面找不到,就会崩
}
@property (nonatomic ,copy) NSString *name;

@property (nonatomic ,assign) float price;

@property (nonatomic ,copy) NSString *content;

@end

知识点 一

KVO与常规赋值的对比:
KVO:

[product setValue:@"小明" forKey:@"name"];

常规赋值:

product.name = @"小明";

在我的项目中使用了两种方式:一种是直接使用字典来监测,还有一种是直接使用对象来监测,在此只说明对象来监测的。

核心代码如下:

/**
     对象
     */
    pl = [[ProductList alloc]init];
    [pl.product setValue:@"水果" forKey:@"name"];
    [pl.product setValue:@"10.1" forKey:@"price"];
    [pl.product setValue:@"水果很甜,值得一吃" forKey:@"content"];
    [pl setValue:pl.product forKey:@"object"];

    [pl addObserver:self forKeyPath:@"object" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];
    //for循环添加对象到数组中
    for (int i = 0; i < 10; i ++) {
        Product *p = [[Product alloc]init];
        [p setValue:[NSString stringWithFormat:@"鞋子%d",i] forKey:@"name"];
        [p setValue:@(10*i) forKey:@"price"];
        [p setValue:[NSString stringWithFormat:@"%d质量不错,很好,也很适合",i] forKey:@"content"];
        [zhuangbeiArr addObject:p];
    }

定义三个label和一个button,用来显示效果,当触发Button时切换到下一个

[pl setValue:zhuangbeiArr[index] forKey:@"object"];

分别在三个Lable上显示:

/**
     *  通过对象实现切换
     *
     *  @return <#return value description#>
     */

    if ([keyPath isEqualToString:@"object"]) {
        Product *p = [pl valueForKey:@"object"];
        label.text = [p valueForKey:@"name"];
        label1.text = [NSString stringWithFormat:@"%@",[p valueForKey:@"price"]];
        label2.text = [p valueForKey:@"content"];
    }

当执行完后,别忘记移除

- (void)dealloc{

    /**
     *  移除KVO
     */
    [pl removeObserver:self forKeyPath:@"object"];
    [product removeObserver:self forKeyPath:@"dic"];
}

对于KVO来说,我们要做的只是简单update 我们的property数据,不需要像NSNotificationCenter那样关心是否有人在监听你的请求,如果没有人监听该怎么办, 所有addObserver, removeObserver, callback 都是想要监听的你的property的class做的事情。 曾经做个项目,用NSNotificationCenter post Notification在一个network callback里面,可是这时候因为最早的addObserver的class被释放了, 接着生成的addObserver的class, 就接受到了上一个observer该监听的事件,所以造成了错误,那时候的解决方案是为addObserve key做unique,不会2次addObserver 的key是相同的,但是有了KVO, 我们同样可以用KVO来完成,当addOberver的的object remove的时候,就不会有这样的callback被调用了。

KVO给我们提供了更少的代码,和比NSNotification好处,不需要修改被观察的class, 永远都是观察你的人做事情。 但是KVO也有些毛病, 1. 如果没有observer监听key path, removeObsever:forKeyPath:context: 这个key path, 就会crash, 不像NSNotificationCenter removeObserver。 2. 对代码你很难发现谁监听你的property的改动,查找起来比较麻烦。 3. 对于一个复杂和相关性很高的class,最好还是不要用KVO, 就用delegate 或者 notification的方式比较简洁。

源码下载:http://download.csdn.net/detail/iosweb/9648409

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值