iOS设计模式之观察者模式

作者: 大兵布莱恩特 | 来源:发表于2018-06-13 19:47 被阅读115次

    iOS 常见的观察者模式主要有通知和 KVO 这两种,通知可以实现一对多的关系, KVO 可以观察属性值的变化.虽然小编开发中经常用到观察者模式这种设计模式,但总觉得理解不是很深入 .

    通知模式

    image.png

    KVO 监听

    image.png

    下边会用一个例子详细的阐述观察者这种设计模式具体使用场景

    image.png

    这是一个酒店里经常可以看到的墙上挂的不同时区时间的钟表,我们以我国东八区北京时间为基准,当北京时间发生改变 ,其他几个城市时间也会相应的发生改变

    首先定义一个 观察者对象的基类

    
    
    /**
     观察者对象
     */
    @interface Observer : NSObject
    {
    @public
        int _hour;
        int _min;
        int _sec;
    }
    
    /**
     改变时 分 秒
     */
    - (void)updateHour:(int)hour minute:(int)min  seconds:(int)sec;
    
    @end
    
    
    

    ///美国标准时间观察者

    
    /**
     美国标准时间
     */
    @interface AmericaTimerObserver : Observer
    
    @end
    
    
    #import "AmericaTimerObserver.h"
    
    @implementation AmericaTimerObserver
    
    - (void)updateHour:(int)hour minute:(int)min seconds:(int)sec {
        NSAssert((hour >= 0 && hour<=23),@"Hour 必须0~23之间");
        NSAssert((min>=0&& min<=59),@"Min 必须0~59之间");
        NSAssert((sec>=0&& sec<=59),@"Sec 必须0~59之间");
        _hour = MIN(hour-13,24);
        if (_hour < 0) {
            _hour = 24 + _hour;
        }
        if (_hour == 24) {
            _hour = 0;
        }
        _min = min;
        _sec = sec;
        [self dis];
    }
    
    /**
     输出美国当前时间
     */
    - (void) dis {
        printf("\n************************\n");
        printf("America Time is update\n");
        printf("H: %d M: %d S:%d\n",_hour,_min,_sec);
    }
    
    @end
    
    
    

    东京时间观察者对象

    
    /**
     日本标准时间
     */
    @interface JapanTimerObserver : Observer
    
    @end
    
    
    #import "JapanTimerObserver.h"
    
    @implementation JapanTimerObserver
    
    - (void)updateHour:(int)hour minute:(int)min seconds:(int)sec {
        NSAssert((hour >= 0 && hour<=23),@"Hour 必须0~23之间");
        NSAssert((min>=0&& min<=59),@"Min 必须0~59之间");
        NSAssert((sec>=0&& sec<=59),@"Sec 必须0~59之间");
        _hour = MIN(hour+1,24);
        if (_hour == 24) {
            _hour = 0;
        }
        _min = min;
        _sec = sec;
        [self dis];
    }
    
    /**
     输出美国当前时间
     */
    - (void) dis {
        printf("\n************************\n");
        printf("Jppan Time is update\n");
        printf("H: %d M: %d S:%d\n",_hour,_min,_sec);
    }
    
    @end
    
    

    然后创建一个订阅者基类对象 只声明接口 并不负责具体实现

    
    #import <Foundation/Foundation.h>
    @class Observer;
    
    @interface Subject : NSObject
    {
    @public
        NSMutableArray <Observer *> *_observerList;
    }
    
    /**
     注册通知
     */
    - (void) registerObserver:(Observer *)ob;
    
    /**
     移除通知
     */
    - (void) removeObserver:(Observer *)ob;
    
    /**
     通知所有监听通知的对象
     */
    - (void) notify;
    
    @end
    
    
    
    

    子类 北京时间订阅者对象

    
    /**
     标准的北京时间
     */
    @interface PekingTimeSubject : Subject
    {
    @private
        int _hour;
        int _min;
        int _sec;
    }
    
    - (void) setTimerHour:(int)hour minute:(int)min seconds:(int)sec;
    
    @end
    
    
    #import "Observer.h"
    #import "PekingTimeSubject.h"
    
    @implementation PekingTimeSubject
    
    
    - (instancetype)init
    {
        self = [super init];
        if (self) {
            _observerList = [NSMutableArray array];
        }
        return self;
    }
    
    - (void)setTimerHour:(int)hour minute:(int)min seconds:(int)sec {
        NSAssert((hour >= 0 && hour<=23),@"Hour 必须0~23之间");
        NSAssert((min>=0&& min<=59),@"Min 必须0~59之间");
        NSAssert((sec>=0&& sec<=59),@"Sec 必须0~59之间");
        _hour = hour;
        _min = min;
        _sec = sec;
        [self dis];
        [self notify];
    
    }
    
    - (void) dis {
        printf("\n************************\n");
        printf("Beijing Time is update\n");
        printf("H: %d M: %d S:%d\n",_hour,_min,_sec);
    }
    
    - (void)notify {
        
        for (Observer *observer in _observerList) {
            [observer updateHour:_hour minute:_min seconds:_sec];
        }
        
    }
    
    - (void)registerObserver:(Observer *)ob {
        [_observerList addObject:ob];
    }
    
    - (void)removeObserver:(Observer *)ob {
        [_observerList removeObject:ob];
    }
    
    @end
    
    
    

    具体使用示例代码

    
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            NSLog(@"Hello, World!");
            
            PekingTimeSubject *bjTime = [[PekingTimeSubject alloc] init];
            JapanTimerObserver *jp = [[JapanTimerObserver alloc] init];
            AmericaTimerObserver *am = [[AmericaTimerObserver alloc] init];
            
            [bjTime registerObserver:jp];
            [bjTime registerObserver:am];
            [bjTime setTimerHour:10 minute:0 seconds:0];
            
            [bjTime removeObserver:jp];
            
            [bjTime setTimerHour:12 minute:0 seconds:0];
            
        }
        return 0;
    }
    
    
    
    image.png

    当注册一个观察者对象后 如果北京时间改变了 那么订阅了这个通知的对象 也会跟着改变

    相关文章

      网友评论

        本文标题:iOS设计模式之观察者模式

        本文链接:https://www.haomeiwen.com/subject/ffdseftx.html