IOS 的 KVO机制

IOS 的 KVO机制

概述

Key-Value Observing (简写为KVO):当指定的对象的属性被修改了,允许对象接受到通知的机制。每次指定的被观察对象的属性被修改的时候,KVO都会自动的去通知相应的观察者。

KVO优点

当有属性改变,KVO会提供自动的消息通知。这样的架构有很多好处。首先,开发人员不需要自己去实现这样的方案:每次属性改变了就发送消息通知。这是KVO 机制提供的最大的优点。因为这个方案已经被明确定义,获得框架级支持,可以方便地采用。开发人员不需要添加任何代码,不需要设计自己的观察者模型,直接可 以在工程里使用。其次,KVO的架构非常的强大,可以很容易的支持多个观察者观察同一个属性,以及相关的值。

实例

假设一个场景,电影票的价格显示在当前屏幕上,当电影票价格更改的时候,实时显示更新其价格

1、定义DataModel
#import <Foundation/Foundation.h>
@interface MovieTicket : NSObject
@property (nonatomic, strong) NSString *title;
@property (nonatomic, assign) float price;
@end

#import "MovieTicket.h"
@implementation MovieTicket
@end
2、viewControl界面

这里写图片描述

3、viewControl代码
#import "ViewController.h"
#import "MovieTicket.h"

NSString *const kChange = @"change";

@interface ViewController ()

@property (weak, nonatomic) IBOutlet UILabel *titleLab;
@property (weak, nonatomic) IBOutlet UILabel *priceLab;

@property (nonatomic, strong) MovieTicket *ticket;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    MovieTicket *ticket = [[MovieTicket alloc] init];
    ticket.title = @"钢铁侠";
    ticket.price = 1.99;

    self.titleLab.text = ticket.title;
    self.priceLab.text = [NSString stringWithFormat:@"%f", ticket.price];

    // 1、 注册,制定被观察者的属性,被观察者是 ticket,观察者是当前控制器
    // 注意: 对象之间建立连接,而不是两个类之间
    [ticket addObserver:self forKeyPath:kChange options:0 context:NULL];

    // 单独观察 ticket 的 price 属性,不需要实现 willChangeValueForKey: 和    didChangeValueForKey:方法
    //[ticket addObserver:self forKeyPath:@"price" options:0 context:NULL];

    self.ticket = ticket;
}

- (void)dealloc {

    // 3、移除观察
    [self.ticket removeObserver:self forKeyPath:kChange];
}

// 点击 "改变票价" 模拟 改变属性
- (IBAction)changePriceBtnClick:(id)sender {
    // 将改变属性的代码写在 willChangeValueForKey: 和 didChangeValueForKey: 之间
    [self.ticket willChangeValueForKey:kChange];
    self.ticket.title = @"美国队长";
    self.ticket.price = arc4random();
    [self.ticket didChangeValueForKey:kChange];
}

// 2、在观察者中实现回调方法,当被观察者的监听的属性发生改变时调用
- (void)observeValueForKeyPath:(NSString *)keyPath
                  ofObject:(id)object
                    change:(NSDictionary<NSString *,id> *)change
                   context:(void *)context {

    if ([keyPath isEqualToString:kChange]) {
    self.titleLab.text = self.ticket.title;
    self.priceLab.text = [NSString stringWithFormat:@"%f", self.ticket.price];
    }

    if ([keyPath isEqualToString:@"price"]) {

    }
}
@end

参考资料

http://www.cnblogs.com/pengyingh/articles/2383629.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值