標籤:
KVO即鍵值觀察者,它提供了一個觀察者模式,用於監聽某個對象屬性值的變化,可以實現一個觀察者,一個被觀察者,多個接收者之間的通訊關係。
KVO的工作流程:
1.被觀察者屬性發生變化(child對象的cleanValue發生變化)
2.觀察者監聽到屬性的變化(KVO幫我們實現了觀察者的商務邏輯)
3.觀察者會調用觀察者方法通知到事件的接收者(觀察者通知到保姆)
4.事件接收者響應這個事件。
在接收者類中添加小孩的觀察者,對象寫self,下面實現觀察者方法,其中改變小孩的相關屬性值,最後手動移除觀察者
相關方法:
1、添加觀察者的方法:
_child:被觀察者
addObserver:事件的接收者
options:表示在觀察者方法的change參數中能夠擷取的值。
context:傳遞的參數
[_childaddObserver:selfforKeyPath:@"cleanValue"options:NSKeyValueObservingOptionNewcontext:NULL];
2、觀察者響應事件的方法:
//keyPath:被觀察者監聽的屬性名稱
//object:被觀察者
//change:是一個字典,提供了關於KVO的有效資訊,比如key:new時表示的是屬性變化後的新值,key:old表示的是屬性變化前的舊值
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {}
舉例:小孩髒了,需要保姆來打理
給小孩添加一個觀察者,事件的接收者是保姆,觀察者把小孩潔淨度這個屬性值傳遞到保姆,保姆去響應打理小孩的方法。
#import "Child.h"@implementation Child- (instancetype)init { if (self = [super init]) { _cleanValue = 100; _happyValue = 100; } [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES]; return self;}- (void)timerAction:(NSTimer *)timer { //1.只有通過兩種方式進行屬性值的設定才能被KVO所監聽到// (1)用setter方法// (2)KVC //這種方法不能被KVO監聽到// _cleanValue--;// _happyValue--; self.cleanValue = _cleanValue - 1; self.happyValue = _happyValue - 1; NSLog(@"cleanValue:%li,happyValue:%li", _cleanValue, _happyValue); }@end
#import "Nanny.h"#import "Child.h"@implementation Nanny- (instancetype)initWithChild:(Child *)child { if (self = [super init]) { _child = child; //使用KVO來監聽小孩屬性值的變化,需要給小孩添加一個觀察者,必須在註冊觀察者以後才能夠監聽到小孩屬性值的變化。 /* 給被觀察者註冊一個觀察者,來監聽被觀察者屬性的變化。 _child:被觀察者 addObserver:事件的接收者 options:表示在觀察者方法的change參數中能夠擷取的值。 context:傳遞的參數 */ [_child addObserver:self forKeyPath:@"cleanValue" options:NSKeyValueObservingOptionNew context:NULL]; [_child addObserver:self forKeyPath:@"happyValue" options:NSKeyValueObservingOptionNew context:NULL]; } return self; }- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context { //keyPath:被觀察者監聽的屬性名稱//object:被觀察者//change:是一個字典,提供了關於KVO的有效資訊,比如key:new時表示的是屬性變化後的新值,key:old表示的是屬性變化前的舊值 NSLog(@"%@", change); if ([keyPath isEqualToString:@"cleanValue"]) { NSNumber *newValue = change[@"new"]; if ([newValue integerValue] < 95) { //保姆針對小孩髒了事件的處理代碼 NSLog(@"保姆給小孩洗白白"); _child.cleanValue = 100; } } else if ([keyPath isEqualToString:@"happyValue"]) { NSNumber *newValue = change[@"new"]; if ([newValue integerValue] < 90) { //保姆針對小孩髒了事件的處理代碼 NSLog(@"保姆逗小孩開心"); _child.happyValue = 100; } } //用KVO也實現了小孩和保姆之間的通訊,小孩可以脫離保姆而存在,進行解耦合,如果想換一個照顧小孩的類,只要在類中添加觀察者,並且實現觀察者方法就可以。 }- (void)dealloc { //在保姆對象被釋放之前,要移除觀察者。ARC無法幫我們完成。 [_child removeObserver:self forKeyPath:@"cleanValue"]; [_child removeObserver:self forKeyPath:@"happtValue"]; }@end
iOS開發————通訊方式之KVO