观察者模式是设计模式的一种,又称为发布者/订阅者模式,其定义了一种一对多的关系,多个观察者可以监听一个对象。当该对象的状态发生改变时,会通知所有的观察者,观察者会自己进行更新。
观察者模式能够将观察者和被观察者解耦,被观察者不需要知道观察者是如何更新的,只需要在自己的状态发生改变时,通知观察者即可。
在实际工作中,当一个对象的改变,同时需要改变其他对象,且不确定有多少对象需要改变的时候,可以使用观察者模式。
在实现观察者模式时,观察者需要实现相应的更新方法;被观察者需要实现增加观察者、移除观察者、向观察者发送通知的方法。
举个例子,有两个模型对象,分别是老师和学生,其中学生是观察者,老师是被观察者。当老师的手机号发生改变时,会向学生发出通知,这样所有学生的“老师的电话号”这个属性就会更新。
实现代码:
观察者对象:
- (instancetype)initWithName:(NSString *)name
{
if(self = [super init]){
self.name = name;
self.teacherNum = @"";
}
return self;
}
// 观察者实现更新方法
- (void)updateTeacherPhone:(NSString *)phone
{
self.teacherNum = phone;
}
被观察者对象:
- (instancetype)initWithName:(NSString *)name
{
if(self = [super init]){
self.name = name;
self.phoneNum = @"";
self.observersArray = [NSMutableArray array];
}
return self;
}
// 增加观察者对象
- (void)addObserver:(Student *)stu
{
if(![self.observersArray containsObject:stu]){
[self.observersArray addObject:stu];
}
}
// 移除某个观察者对象
- (void)removeObserver:(Student *)stu
{
if([self.observersArray containsObject:stu]){
[self.observersArray removeObject:stu];
}
}
// 向所有的观察者对象发出通知
- (void)notificationObserver
{
for(int i = 0; i < self.observersArray.count ; ++i){
Student *stu = [self.observersArray objectAtIndex:i];
if([stu respondsToSelector:@selector(updateTeacherPhone:)]){
[stu updateTeacherPhone:self.phoneNum];
}
}
}
在main函数中调用:
Student *jhon = [[Student alloc] initWithName:@"jhon"];
Student *tom = [[Student alloc] initWithName:@"tom"];
Teacher *teacher = [[Teacher alloc] initWithName:@"Green"];
// 增加观察者
[teacher addObserver:jhon];
[teacher addObserver:tom];
teacher.phoneNum = @"123456";
// 通知所有的观察者进行更新
[teacher notificationObserver];
NSLog(@"jhon teacherPhone = %@",jhon.teacherNum);
NSLog(@"tom teacherPhone = %@",tom.teacherNum);
// 移除一个观察者
[teacher removeObserver:jhon];
teacher.phoneNum = @"654321";
// 通知所有的观察者进行更新
[teacher notificationObserver];
NSLog(@"jhon teacherPhone = %@",jhon.teacherNum);
NSLog(@"tom teacherPhone = %@",tom.teacherNum);
输出结果:
jhon teacherPhone = 123456 tom teacherPhone = 123456 jhon teacherPhone = 123456 tom teacherPhone = 654321
可以看到,被观察者将某个观察者移除后,被观察者状态发生改变并通知观察者,被移除的观察者状态不变。
实际上,在iOS开发中,KVO以及消息中心都是使用观察者模式实现的。