kvo,與觀察者模式類似,通過給指定的對象設(shè)置觀察者,來檢測對象的變化,當(dāng)指定的對象的屬性被修改后,用于作為觀察者的對象會接收到通知。簡單的說就是每次指定的被觀察的對象的屬性被修改后,kvo就會自動(dòng)通知相應(yīng)的觀察者。系統(tǒng)框架已經(jīng)支持kvo,所以在開發(fā)過程中可以直接使用,非常方便。
一、kvo的使用步驟 |
1、注冊,指定被觀察者的屬性
2、實(shí)現(xiàn)回調(diào)方法
3、移除觀察
二、通過現(xiàn)實(shí)中的小例子介紹一下kvo的用法 |
我有一張銀行卡,只要卡內(nèi)的金額發(fā)生的改變,銀行就會發(fā)短信給我提示,下面通過代碼使用kvo來模擬一下這個(gè)過程
先創(chuàng)建一個(gè)Card銀行卡類,卡里有money金額的屬性,在初始化這張卡的時(shí)候,給卡里金額設(shè)置一個(gè)初值1000,然后每隔1秒鐘模擬消費(fèi)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;}//改變卡內(nèi)金額-(void)changeMoney{ self.money -= 10; }@end
再創(chuàng)建一個(gè)People人類,在這個(gè)類中有姓名name和card銀行卡兩個(gè)屬性。
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
創(chuàng)建好了兩個(gè)類之后,在People類中通過kvo來監(jiān)測銀行卡中金額的變化
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;
調(diào)用方法的是被監(jiān)聽的對象,參數(shù)分別為:
addObserver:觀察者
forKeyPath:被監(jiān)聽的對象的屬性,屬性里面還有屬性的,可以用點(diǎn)語法
options:想監(jiān)聽的對象是什么操作,比如初始化、有新的值
context:上下文,一般為nil,當(dāng)KeyPath:相同時(shí),可以用它來區(qū)分
因此,在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;}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
observeValueForKeyPath:字符串,被監(jiān)聽的屬性
ofObject:哪一個(gè)對象被監(jiān)聽
change:字典,包含了變化前和變化后的值
context:上下文
因此,在People.m中需要實(shí)現(xiàn)回調(diào)方法
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ NSLog(@"回調(diào)方法 %@",change);}
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;
調(diào)用方法的是被監(jiān)聽的對象
removeObserver:觀察者
forKeyPath:字符串
因此,在People.m中重寫dealloc方法,實(shí)現(xiàn)移除監(jiān)聽者
-(void)dealloc{ [_card removeObserver:self forKeyPath:@"money"];}
例子中Card類中有一個(gè)changeMoney方法,在這個(gè)方法中修改了被監(jiān)聽屬性的值,下面介紹4中方法給大家。
-(void)changeMoney{ //不能直接改值!!!! _money -= 10; //錯(cuò)誤的 //1.點(diǎn)語法 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"]; }
如有疑問咨詢或技術(shù)交流,請加入官方QQ群: (452379712)
新聞熱點(diǎn)
疑難解答
圖片精選