ObjC-观察者模式
观察者模式是设计模式的一种,又称为发布者/订阅者模式,其定义了一种一对多的关系,多个观察者可以监听一个对象。当该对象的状态发生改变时,会通知所有的观察者,观察者会自己进行更新。
观察者模式能够将观察者和被观察者解耦,被观察者不需要知道观察者是如何更新的,只需要在自己的状态发生改变时,通知观察者即可。
在实际工作中,当一个对象的改变,同时需要改变其他对象,且不确定有多少对象需要改变的时候,可以使用观察者模式。
在实现观察者模式时,观察者需要实现相应的更新方法;被观察者需要实现增加观察者、移除观察者、向观察者发送通知的方法。
举个例子,有两个模型对象,分别是老师和学生,其中学生是观察者,老师是被观察者。当老师的手机号发生改变时,会向学生发出通知,这样所有学生的“老师的电话号”这个属性就会更新。
实现代码:
观察者对象:
- (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以及消息中心都是使用观察者模式实现的。