iOS设计模式之观察者模式

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 开发交流群

QQ20180712-0.png

猜你喜欢

转载自blog.csdn.net/dzb1060545231/article/details/80685131
今日推荐