IOS Key-Value Observing (KVO)

  kvo,与观察者模式类似,通过给指定的对象设置观察者,来检测对象的变化,当指定的对象的属性被修改后,用于作为观察者的对象会接收到通知。简单的说就是每次指定的被观察的对象的属性被修改后,kvo就会自动通知相应的观察者。系统框架已经支持kvo,所以在开发过程中可以直接使用,非常方便。

一、kvo的使用步骤

1、注册,指定被观察者的属性

2、实现回调方法

3、移除观察

二、通过现实中的小例子介绍一下kvo的用法

  我有一张银行卡,只要卡内的金额发生的改变,银行就会发短信给我提示,下面通过代码使用kvo来模拟一下这个过程

  先创建一个Card银行卡类,卡里有money金额的属性,在初始化这张卡的时候,给卡里金额设置一个初值1000,然后每隔1秒钟模拟消费10元,代码如下:

  Card.h

//  Card.h
//  KVO
//
//  Created by jerei on 15-6-5.
//  Copyright (c) 2015年 jerehedu. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Card : NSObject

@property (nonatomic, assign) float money;

@end

  Card.m

//  Card.m
//  KVO
//
//  Created by jerei on 15-6-5.
//  Copyright (c) 2015年 jerehedu. All rights reserved.
//

#import "Card.h"

@implementation Card

-(instancetype)init
{
    if (self = [super init]) {
        _money = 1000.0;
        
        [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(changeMoney) userInfo:nil repeats:YES];
    }
    return self;
}

//改变卡内金额
-(void)changeMoney
{
    self.money -= 10;    
}

@end

  再创建一个People人类,在这个类中有姓名name和card银行卡两个属性。

  People.h

//  People.h
//  KVO
//
//  Created by jerei on 15-6-5.
//  Copyright (c) 2015年 jerehedu. All rights reserved.
//

#import <Foundation/Foundation.h>

@class Card;

@interface People : NSObject

@property (nonatomic, copy) NSString *name;
@property (nonatomic, strong) Card *card;

-(id)initWithName:(NSString *)name andCard:(Card *)card;

@end

  People.m

//  People.m
//  KVO
//
//  Created by jerei on 15-6-5.
//  Copyright (c) 2015年 jerehedu. All rights reserved.
//

#import "People.h"
#import "Card.h"

@implementation People

-(id)initWithName:(NSString *)name andCard:(Card *)card
{
    if (self = [super init]) {
        _name = name;
        _card = card;
    }
    
    return self;
}

@end

  创建好了两个类之后,在People类中通过kvo来监测银行卡中金额的变化

1、人需要监听银行账户中的金额,需要注册监听对象

- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;

  调用方法的是被监听的对象,参数分别为:

addObserver:观察者

forKeyPath:被监听的对象的属性,属性里面还有属性的,可以用点语法

options:想监听的对象是什么操作,比如初始化、有新的值

context:上下文,一般为nil,当KeyPath:相同时,可以用它来区分

  因此,在People.m中需要添加的代码为:

-(id)initWithName:(NSString *)name andCard:(Card *)card
{
    if (self = [super init]) {
        _name = name;
        _card = card;
   
        //注册,添加观察者
        [_card addObserver:self forKeyPath:@"money" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
    }
    
    return self;
}

2、一旦注册了,就可以去回调函数中感知变化过程

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

observeValueForKeyPath:字符串,被监听的属性

ofObject:哪一个对象被监听

change:字典,包含了变化前和变化后的值

context:上下文

  因此,在People.m中需要实现回调方法

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"回调方法 %@",change);
}

3、解除监听对象

- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;

  调用方法的是被监听的对象

removeObserver:观察者

forKeyPath:字符串

  因此,在People.m中重写dealloc方法,实现移除监听者

-(void)dealloc
{
    [_card removeObserver:self forKeyPath:@"money"];
}

4、ps: kvo属性值改变时,不能直接改值

  例子中Card类中有一个changeMoney方法,在这个方法中修改了被监听属性的值,下面介绍4中方法给大家。

-(void)changeMoney
{
    //不能直接改值!!!!
    _money -= 10; //错误的
    
    //1.点语法
    self.money -= 10;
    
    //2. set方法
    float f = _money-10;
    [self setMoney:f];
    
    //3. kvc
    [self setValue:@(f) forKey:@"money"];
    
    //4.
    [self willChangeValueForKey:@"money"];
    _money -= 10;
    [self didChangeValueForKey:@"money"];
    
}

 

  如有疑问咨询或技术交流,请加入官方QQ群:JRedu技术交流 (452379712)

作者: 杰瑞教育
出处: http://blog.csdn.net/jerehedu/ 
本文版权归烟台杰瑞教育科技有限公司和CSDN共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值