什么是观察者模式
观察者模式定义了对象间的一种一对多依赖关系,让多个观察者对象同时监听某一个对象,使得每当该对象的状态发生改变的时候,会通知所有观察者对象并自动更新。
iOS 中典型的推模型实现方式
iOS 中典型的推模型实现方式有 NSNotificationCenter
和 KVO
。
NSNotificationCenter
1.观察者通过 NSNotificationCenter
的addObserver:selector:name:object
接口来注册对某一类型通知感兴趣。
[notificationCenter addObserver:self selector:@selector(update:) name:@"updateMessage" object:nil];
- (void)update:(NSNotification*)notification {
if ([[notification name] isEqualToString:@"updateMessage"]) {
NSLog(@"%@",@"update");
}
}
2.通知中心 NSNotificationCenter
,通知的枢纽。
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
3.被观察的对象通过 postNSNotificationName:object:userInfo
发送通知。
NSNotification *updateMessage = [NSNotification notificationWithName:@"updateMessage" object:self];
[notificationCenter postNotification:updateMessage];
4.当有通知来的时候,NSNotificationCenter
会调用观察者注册的接口来广播通知,同时传递存储着更改内容的 NSNotification对象
。
5.注销通知。
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
KVO
KVO 的全称是 Key-Value Observer,即键值观察。是一种没有中心枢纽的观察者模式的实现方式。一个主题对象管理所有依赖于它的观察对象,并在自身状态发生改变的时候主动通知观察者对象。
1.注册观察者。
2.更改主题对象属性的值,触发发送更改的通知。
3.在定义的回调函数中处理收到的更改通知。
4.注销观察者。
下面是一个例子
首先定义一个 Car 模型
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *type;
@property (nonatomic, assign) NSUInteger *price;
将模型定义控制器的属性,实例化并监听其属性
- (void)viewDidLoad {
[super viewDidLoad];
self.car = [[Car alloc] init];
self.car.name = @"Tesla Model X";
self.car.type = @"SUV";
self.car.price = 1000000;
[self.car addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
[self.car addObserver:self forKeyPath:@"type" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
}
点击屏幕时,修改对象属性
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
self.car.name = @"Tesla Model S";
self.car.type = @"Seden";
}
实现回调方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if([keyPath isEqualToString:@"name"]) {
NSLog(@"当前值: %@",self.car.name);
NSLog(@"修改前: %@",change[@"old"]);
NSLog(@"修改后: %@",change[@"new"]);
}
if([keyPath isEqualToString:@"type"]) {
NSLog(@"当前值: %@",self.car.type);
NSLog(@"修改前: %@",change[@"old"]);
NSLog(@"修改后: %@",change[@"new"]);
}
}
运行得到以下结果
最后注销观察者
- (void)dealloc {
[self.car removeObserver:self forKeyPath:@"name"];
[self.car removeObserver:self forKeyPath:@"type"];
}
最后
本人为iOS开发新手一枚,写的不好的或写错的地方,希望各位大侠能帮忙指正。
各位大侠,如果觉得对自己有点用的,欢迎点个赞,也欢迎大家关注我( Github / 简书 / 微博 / Instagram / 知乎)
谢谢观看此文。
网友评论