KVO 是 key/value/observing 的缩写
个人理解的意思是:当对应的key的值value发生改变时,通知observer观察者执行一些操作.
基本就是一个观察者模式,和事件模型一模一样.
// 当前事件发布者是 ChangeMyProperty对象
// 当前的事件订阅者是 MyObserverObj对象.
//
//先浅显的解释一下啥是KVO.
//KVO = key / value / observing.
//当被被观察者的某个属性发生变化的时候,会通知观察者执行一些事情.
ChangeMyProperty *cp = [[ChangeMyProperty alloc] init];
//定义观察者
MyObserverClass *mc = [[MyObserverClass alloc] init];
//注册观察者
//当cp的name属性调用setter方法,就会通知mc对象处理相关操作.
[cp addObserver:mc forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
cp.name = @"张三";
[cp removeObserver:mc forKeyPath:@"name"];
属性发生改变时的事件响应方法.
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
NSLog(@"被监控的属性是:%@",keyPath);
NSLog(@"被监控的对象类型是:%@",[object className]);
NSLog(@"值放生了变化啦!!!");
}
最终结果:
KVO事件响应函数输出的结果可以看出:
第一个参数是[被监控对象的属性].
第二个参数是[被监控对象的类型].
也就是所谓的事件发布者的类型和属性.
既然是key的value发生改变,那么一定是在key的setter方法的时候,发出通知.
所以开始尝试自己模拟最简单的第一版KVO.
核心思想是:当一个对象的某个属性发生改变时(也就是调用setter方法的时候),通知事件订阅者执行某些操作.
//事件发布者的代码声明
#import <Foundation/Foundation.h>
@class ObjObserver;//事件订阅者
@interface EventSender : NSObject
@property (nonatomic,copy) NSString *name;
- (void)myAddObserver:(ObjObserver*)observer forKeyPath:(NSString *)path;
@end
//事件发布者的代码实现
#import "EventSender.h"
#import "ObjObserver.h"
@interface EventSender ()
@property (nonatomic,strong) ObjObserver *observer;
@end
@implementation EventSender
- (void)myAddObserver:(ObjObserver *)observer forKeyPath:(NSString *)path
{
//绑定事件响应者
if(observer == nil) return;
self.observer = observer;
}
- (void)setName:(NSString *)name
{
_name = name;
//在name属性发生改变时执行事件响应者的相关函数
if (self.observer != nil) {
[self.observer methodForKvo:name];
}
}
@end
事件响应者的相关代码
#import "ObjObserver.h"
@implementation ObjObserver
- (void)methodForKvo:(NSString *)value
{
NSLog(@"模拟KVO变化的第一版成功!");
NSLog(@"变化的属性值是:%@",value);
}
@end
main.m文件
#import <Foundation/Foundation.h>
#import "EventSender.h"
#import "ObjObserver.h"
int main(int argc, const char * argv[]) {
//KVO - key/value/observering
//当某个对象的某个属性值发生变化时,会通知观察者执行某些特定的操作.
//注册事件发布者
EventSender *es = [[EventSender alloc] init];
//注册KVO观察者
ObjObserver *ob = [[ObjObserver alloc] init];
//添加观察者
[es myAddObserver:ob forKeyPath:@"name"];
es.name = @"事件发布者对象者调用setter方法";
return 0;
}
最后执行结果截图:
尝试实现KVO第一版V1.0最后粗浅的结论:
KVO本质上,就是两个对象.
一个事件发布者,在自己的某些属性的值发生改变时,通知事件响应者执行某些方法.
一个是事件响应者,被事件发布者绑定到自己的某些属性的改变行为上.当属性发生改变时
被动的被事件发布者执行相关的函数.
画一张自己理解的图:
KVO简单理解
网友评论