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以及消息中心都是使用观察者模式实现的。

原文地址:https://www.cnblogs.com/acBool/p/5537463.html