美文网首页
iOS 观察者模式

iOS 观察者模式

作者: 印林泉 | 来源:发表于2017-03-05 21:45 被阅读61次
    • 观察者模式
      用户在订阅中心注册订阅号,通知中心往订阅号发消息,用户接收消息,执行通知中心协议方法。
      系统通知中心使用后必须释放,自定义通知中心可以实现优化。

    • 应用,适用场景
      订阅中心

    自定义通知中心

    //
    //  SubscriptionServiceCenter.h
    //  LearnObserver
    //
    //  Created by 印林泉 on 2017/3/5.
    //  Copyright © 2017年 yiq. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    #import "SubscriptionServiceCenterProtocol.h"
    
    @interface SubscriptionServiceCenter : NSObject
    
    #pragma mark - 维护订阅信息
    ///创建订阅号
    + (void)createSubscriptionNumber:(NSString *)subscriptionNumber;
    ///移除订阅号
    + (void)removeSubscriptionNumber:(NSString *)subscriptionNumber;
    
    #pragma mark - 维护客户信息
    ///添加客户到具体的订阅号当中
    + (void)addCustomer:(id <SubscriptionServiceCenterProtocol>)customer withSubscriptionNumber:(NSString *)subscriptionNumber;
    ///从具体的订阅号当中移除客户
    + (void)removeCustomer:(id <SubscriptionServiceCenterProtocol>)customer withSubscriptionNumber:(NSString *)subscriptionNumber;
    
    #pragma mark - 发送消息
    ///发送消息到具体的订阅号当中
    + (void)sendMessage:(id)message toSubscriptionNumber:(NSString *)subscriptionNumber;
    
    @end
    
    //
    //  SubscriptionServiceCenter.m
    //  LearnObserver
    //
    //  Created by 印林泉 on 2017/3/5.
    //  Copyright © 2017年 yiq. All rights reserved.
    //
    
    #import "SubscriptionServiceCenter.h"
    
    static NSMutableDictionary *_subscriptionDictionary = nil;
    
    @implementation SubscriptionServiceCenter
    
    + (void)initialize {
        if (self == [SubscriptionServiceCenter class]) {
            _subscriptionDictionary = [NSMutableDictionary dictionary];
        }
    }
    
    + (void)createSubscriptionNumber:(NSString *)subscriptionNumber {
        NSParameterAssert(subscriptionNumber);
        NSHashTable *hashTable = [self existSubscriptionNumber:subscriptionNumber];
        if (hashTable == nil) {
            hashTable = [NSHashTable weakObjectsHashTable];
            [_subscriptionDictionary setObject:hashTable forKey:subscriptionNumber];
        }
    }
    
    + (void)removeSubscriptionNumber:(NSString *)subscriptionNumber {
        NSParameterAssert(subscriptionNumber);
        NSHashTable *hashTable = [self existSubscriptionNumber:subscriptionNumber];
        if (hashTable) {
            [_subscriptionDictionary removeObjectForKey:subscriptionNumber];
        }
    }
    
    + (void)addCustomer:(id <SubscriptionServiceCenterProtocol>)customer withSubscriptionNumber:(NSString *)subscriptionNumber {
        NSParameterAssert(customer);
        NSParameterAssert(subscriptionNumber);
        NSHashTable *hashTable = [self existSubscriptionNumber:subscriptionNumber];
        [hashTable addObject:customer];
    }
    
    + (void)removeCustomer:(id <SubscriptionServiceCenterProtocol>)customer withSubscriptionNumber:(NSString *)subscriptionNumber {
        NSParameterAssert(subscriptionNumber);
        NSHashTable *hashTable = [self existSubscriptionNumber:subscriptionNumber];
        [hashTable removeObject:customer];
    }
    
    + (void)sendMessage:(id)message toSubscriptionNumber:(NSString *)subscriptionNumber {
        NSParameterAssert(subscriptionNumber);
        NSHashTable *hashTable = [self existSubscriptionNumber:subscriptionNumber];
        if (hashTable) {
            NSEnumerator *enumerator = [hashTable objectEnumerator];
            id <SubscriptionServiceCenterProtocol> object = nil;
            while (object = [enumerator nextObject]) {
                if ([object respondsToSelector:@selector(subscriptionMessage:subscriptionNumber:)]) {
                    [object subscriptionMessage:message subscriptionNumber:subscriptionNumber];
                }
            }
        }
    }
    
    #pragma mark - 私有方法
    + (NSHashTable *)existSubscriptionNumber:(NSString *)subscriptionNumber {
        return [_subscriptionDictionary objectForKey:subscriptionNumber];
    }
    
    @end
    

    自定义通知中心协议

    //
    //  SubscriptionServiceCenterProtocol.h
    //  LearnObserver
    //
    //  Created by 印林泉 on 2017/3/5.
    //  Copyright © 2017年 yiq. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    @protocol SubscriptionServiceCenterProtocol <NSObject>
    
    @required
    - (void)subscriptionMessage:(id)message subscriptionNumber:(NSString *)subscriptionNumber;
    
    @end
    

    使用自定义通知中心

    - (void)viewDidLoad {
        [super viewDidLoad];
        [self customNotificationCenter];
    }
    
    - (void)customNotificationCenter {
        ///创建订阅号
        [SubscriptionServiceCenter createSubscriptionNumber:SCIENCE];
        ///添加订阅的用户到指定的刊物
        [SubscriptionServiceCenter addCustomer:self withSubscriptionNumber:SCIENCE];
        ///发行机构发送消息
        [SubscriptionServiceCenter sendMessage:@"V1.0" toSubscriptionNumber:SCIENCE];
    }
    
    #pragma mark - 自定义通知中心方法
    - (void)subscriptionMessage:(id)message subscriptionNumber:(NSString *)subscriptionNumber {
        NSLog(@"%@  %@", message, subscriptionNumber);
    }
    
    

    使用系统通知中心

    - (void)viewDidLoad {
        [super viewDidLoad];
        [self systemNotificationCenter];
    }
    
    - (void)systemNotificationCenter {
        ///添加客户到指定的订阅号中
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationCenterEvent:) name:SCIENCE object:nil];
        ///发送信息到指定的订阅号当中
        [[NSNotificationCenter defaultCenter] postNotificationName:SCIENCE object:@"V1.0"];
        
        ///创建订阅中心
        self.model = [Model new];
        ///客户添加了订阅中心的"name"服务
        [self.model addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
        ///订阅中心发送消息(通过修改属性值)
        self.model.name = @"V1.0";
    }
    
    #pragma mark - 通知中心方法
    - (void)notificationCenterEvent:(id)sender {
        NSLog(@"%@", sender);
    }
    
    #pragma mark - 释放资源
    - (void)dealloc {
        ///移除通知中心
        [[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:SCIENCE];
    }
    

    系统通知中心KVO实现

    - (void)viewDidLoad {
        [super viewDidLoad];
        [self notificationCenterByKVO];
    }
    
    - (void)notificationCenterByKVO {
        ///创建订阅中心
        self.model = [Model new];
        ///客户添加了订阅中心的"name"服务
        [self.model addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil];
        ///订阅中心发送消息(通过修改属性值)
        self.model.name = @"V1.0";
    }
    
    #pragma mark - KVO方法
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
        NSLog(@"%@", change);
    }
    
    #pragma mark - 释放资源
    - (void)dealloc {
        ///移除KVO
        [self.model removeObserver:self forKeyPath:@"name"];
    }
    

    相关文章

      网友评论

          本文标题:iOS 观察者模式

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