iOS设计模式 - 观察者
原理图
说明
1. cocoa框架本身实现了观察者模式(通知中心以及KVO)
2. 本人所写的例子,实现了通知中心,其特殊的地方在于,不用移除订阅了通知的对象
源码
https://github.com/YouXianMing/iOS-Design-Patterns
//
// SubscriptionServiceCenter.h
// ObserverPattern
//
// Created by YouXianMing on 15/7/29.
// Copyright (c) 2015年 YouXianMing. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "SubscriptionServiceCenterProtocol.h"
/**
* 订阅服务中心(实现了系统的通知中心业务逻辑)
*
* = 注意 = 没有考虑发送通知的时候,同步与异步的问题
*
*/
@interface SubscriptionServiceCenter : NSObject
/**
* 创建订阅号
*
* @param subscriptionNumber 订阅号码
*/
+ (void)createSubscriptionNumber:(NSString *)subscriptionNumber;
/**
* 移除订阅号(参与到该订阅号码的所有客户不会再收到订阅信息)
*
* @param subscriptionNumber 订阅号码
*/
+ (void)removeSubscriptionNumber:(NSString *)subscriptionNumber;
/**
* 将指定客户从指定订阅号上移除掉
*
* @param customer 客户对象
* @param subscriptionNumber 订阅号码
*/
+ (void)removeCustomer:(id <SubscriptionServiceCenterProtocol>)customer fromSubscriptionNumber:(NSString *)subscriptionNumber;
/**
* 通知签订了订阅号码的对象
*
* @param message 信息对象
* @param subscriptionNumber 订阅号码
*/
+ (void)sendMessage:(id)message toSubscriptionNumber:(NSString *)subscriptionNumber;
/**
* 客户订阅指定的订阅号
*
* @param customer 客户对象
* @param subscriptionNumber 订阅号码
*/
+ (void)addCustomer:(id <SubscriptionServiceCenterProtocol>)customer withSubscriptionNumber:(NSString *)subscriptionNumber;
@end
//
// SubscriptionServiceCenter.m
// ObserverPattern
//
// Created by YouXianMing on 15/7/29.
// Copyright (c) 2015年 YouXianMing. All rights reserved.
//
#import "SubscriptionServiceCenter.h"
static NSMutableDictionary *_subscriptionNumberDictionary = nil;
@implementation SubscriptionServiceCenter
#pragma mark - 初始化
+ (void)initialize {
if (self == [SubscriptionServiceCenter class]) {
_subscriptionNumberDictionary = [NSMutableDictionary dictionary];
}
}
+ (void)createSubscriptionNumber:(NSString *)subscriptionNumber {
NSParameterAssert(subscriptionNumber);
NSHashTable *hashTable = [self existSubscriptionNumber:subscriptionNumber];
if (hashTable == nil) {
hashTable = [NSHashTable weakObjectsHashTable];
[_subscriptionNumberDictionary setObject:hashTable forKey:subscriptionNumber];
}
}
+ (void)removeSubscriptionNumber:(NSString *)subscriptionNumber {
NSParameterAssert(subscriptionNumber);
if ([self existSubscriptionNumber:subscriptionNumber]) {
[_subscriptionNumberDictionary removeObjectForKey:subscriptionNumber];
}
}
+ (void)removeCustomer:(id <SubscriptionServiceCenterProtocol>)customer fromSubscriptionNumber:(NSString *)subscriptionNumber {
NSParameterAssert(subscriptionNumber);
NSHashTable *hashTable = [self existSubscriptionNumber:subscriptionNumber];
if (hashTable && customer) {
[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> customer = nil;
while (customer = [enumerator nextObject]) {
if ([customer respondsToSelector:@selector(subscriptionMessage:subscriptionNumber:)]) {
[customer subscriptionMessage:message subscriptionNumber:subscriptionNumber];
}
}
}
}
+ (void)addCustomer:(id)customer withSubscriptionNumber:(NSString *)subscriptionNumber {
NSParameterAssert(customer);
NSParameterAssert(subscriptionNumber);
NSHashTable *hashTable = [self existSubscriptionNumber:subscriptionNumber];
[hashTable addObject:customer];
}
#pragma mark - 私有方法
+ (NSHashTable *)existSubscriptionNumber:(NSString *)subscriptionNumber {
return [_subscriptionNumberDictionary objectForKey:subscriptionNumber];
}
@end
//
// SubscriptionServiceCenterProtocol.h
// ObserverPattern
//
// Created by YouXianMing on 15/7/29.
// Copyright (c) 2015年 YouXianMing. All rights reserved.
//
#import <Foundation/Foundation.h>
@protocol SubscriptionServiceCenterProtocol <NSObject>
/**
* 接收到的订阅信息
*
* @param message 订阅信息
* @param subscriptionNumber 订阅编号
*/
- (void)subscriptionMessage:(id)message subscriptionNumber:(NSString *)subscriptionNumber;
@end
分析
让一个对象,遵循某种制定的协议(接口)来完成特定的功能,是cocoa开发中很重要的一种技巧
订阅以及针对订阅号发布信息的完整流程