觀察者模式
用戶在訂閱中心注冊訂閱號,通知中心往訂閱號發消息,用戶接收消息,執行通知中心協議方法。
系統通知中心使用后必須釋放,自定義通知中心可以實現優化。應用,適用場景
訂閱中心
自定義通知中心
//
// 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"];
}