iOS 觀察者模式

  • 觀察者模式
    用戶在訂閱中心注冊訂閱號,通知中心往訂閱號發消息,用戶接收消息,執行通知中心協議方法。
    系統通知中心使用后必須釋放,自定義通知中心可以實現優化。

  • 應用,適用場景
    訂閱中心

自定義通知中心

//
//  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"];
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 觀察者模式本質上時一種發布-訂閱模型,用以消除具有不同行為的對象之間的耦合,通過這一模式,不同對象可以協同工作,同...
    PlatonsDream閱讀 1,308評論 0 0
  • 什么是觀察者模式?當A對B的變化感興趣,需要監聽B的狀態變化,就注冊為B的觀察者,當B發生變化時通知A,告知B發生...
    _Lily閱讀 1,591評論 2 4
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,045評論 25 708
  • 一.什么是觀察者模式? 簡單的說就是一個對象擁有多個特征,當某一個特征發生變化時,另外一個對象做出相應的處理和操作...
    LYSNote閱讀 4,225評論 0 5
  • 本文整理了幫你的站點創建出一個優秀的“關于”頁面的9個想法: 1、讓訪問者能輕易的聯系到你 在某些情況下,訪問者可...
    三達不留點gpj閱讀 731評論 0 5