iOS 观察者模式
2017-03-05 本文已影响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"];
}