-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
chaidongpeng
committed
Jul 10, 2021
0 parents
commit 9b3ee8e
Showing
33 changed files
with
2,043 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// | ||
// CDPStateManager.h | ||
// stateManager | ||
// | ||
// Created by CDP on 2021/7/10. | ||
// 状态管理类 | ||
|
||
#import <Foundation/Foundation.h> | ||
|
||
#import "CDPStateManagerProtocol.h" | ||
|
||
/// action回调block | ||
typedef NSDictionary *_Nullable(^CDPHandleActionBlock)(NSDictionary * _Nullable parameters); | ||
/// 同步notification状态回调block | ||
typedef NSDictionary *_Nullable(^CDPHandleNotificationBlock)(NSNotification * _Nonnull notification); | ||
|
||
|
||
@interface CDPStateManager : NSObject | ||
/// 使用方法 | ||
/// 1. 用 registerAction 方法注册 改变状态 处理回调 (只用注册一次即可,可在 AppDelegate 初始化时就把各状态注册好) | ||
/// 2. import "CDPStateManager.h",将需要管理的 object 遵守 CDPStateManagerProtocol 协议,并添加进 对应状态 的管理池 | ||
/// 3. 实现 CDPStateManagerProtocol 所需协议方法,接收 状态同步 | ||
/// | ||
/// 其他: | ||
/// 1. 如果某控件需要 主动去改变 某已管理状态,则调用该状态对应 已注册action 即可,即调用 actionWithParameters: stateIdentifier: 方法 | ||
/// 2. 如果需要将 已管理状态 与 已有notification通知 同步,则用 syncNotificationName 方法进行绑定 | ||
|
||
/// 单例对象 | ||
+ (instancetype _Nonnull )defaultManager; | ||
|
||
#pragma mark - 管理控件 | ||
|
||
/// 获取 identifier 对应状态的 object 管理池 | ||
/// @param identifier 对应 状态 唯一标识 | ||
- (NSHashTable *_Nonnull)getHashTableWithIdentifier:(nonnull NSString *)identifier; | ||
|
||
/// 将 相关控件 添加进 identifier 对应 状态管理池 中 (控件释放后 内部会自动对其 移除, 不需要 主动移除) | ||
/// @param object 相关控件 | ||
/// @param identifier 对应 状态 唯一标识 | ||
- (void)addObject:(nonnull id <CDPStateManagerProtocol>)object stateIdentifier:(nonnull NSString *)identifier; | ||
|
||
/// 主动将 相关控件 从 identifier 对应 状态管理池 中移除 | ||
/// @param object 相关控件 | ||
/// @param identifier 对应 状态 唯一标识 | ||
- (void)removeObject:(nonnull id <CDPStateManagerProtocol>)object stateIdentifier:(nonnull NSString *)identifier; | ||
|
||
/// 清空 identifier 对应 状态管理池 (慎用!!!) | ||
/// @param identifier 对应 状态 唯一标识 | ||
- (void)removeAllObjectsWithStateIdentifier:(nonnull NSString *)identifier; | ||
|
||
#pragma mark - action | ||
|
||
/// 注册 identifier 对应状态 相关 action,如果该状态已注册 action,则自动替换 (状态 与 action 一一对应) | ||
/// @param identifier 对应 状态 唯一标识 | ||
/// @param block 进行action回调,进行切换状态等相关逻辑处理 | ||
/// | ||
/// 通过action改变状态时,会将 parameters 通过 block 回调,可以在 block 里根据 传参 进行相关逻辑处理,然后将结果数据通过 字典 封装返回,内部会将该 字典 通过 CDPStateManagerProtocol 协议方法进行全站同步管理 | ||
/// | ||
/// 注:回调 字典 里如果有 @"stateManagerNotSync" : @"1" ,则此次结果 字典 不会进行全站同步 | ||
- (void)registerActionWithStateIdentifier:(nonnull NSString *)identifier | ||
completion:(nonnull CDPHandleActionBlock)block; | ||
|
||
/// 移除 identifier 对应状态 相关 action | ||
/// @param identifier 对应 状态 唯一标识 | ||
- (void)removeActionWithStateIdentifier:(nonnull NSString *)identifier; | ||
|
||
/// 执行 identifier 对应状态 相关 action,以改变状态 (必须先用 registerAction 添加再使用) | ||
/// @param parameters action 改变状态要用到的传参 | ||
/// @param identifier 对应 状态 唯一标识 | ||
- (void)actionWithParameters:(nullable NSDictionary *)parameters | ||
stateIdentifier:(nonnull NSString *)identifier; | ||
|
||
#pragma mark - 同步通知 | ||
/// 如果有状态存在 不通过 CDPStateManager 管理,而是用 notification 通知 管理的情况,可以用以下方法将已管理的 状态 与该通知绑定同步 | ||
|
||
/// 将 notificationName 对应的通知 与 identifier 对应状态 进行同步绑定,使该 状态 可以被 notification 进行状态同步 | ||
/// 状态 与 通知 绑定关系为 多对多,及 一种状态可绑定多个通知 ,一个通知也可同步多个状态 | ||
/// @param notificationName 要同步的广播通知名称 | ||
/// @param identifier 被同步的 对应 状态 唯一标识 | ||
/// @param block 收到 notification 进行的 block 同步回调,进行相关逻辑处理 | ||
/// | ||
/// 当收到 notification 时,会将其通过 block 回调,可以在 block 里根据 收到的 notification 进行相关逻辑处理转换,然后将结果数据通过 字典 封装返回,内部会将该 字典 通过 CDPStateManagerProtocol 协议方法进行全站同步管理 | ||
/// | ||
/// 注:回调 字典 里如果有 @"stateManagerNotSync" : @"1" ,则此次结果 字典 不会进行全站同步 | ||
- (void)syncNotificationName:(nonnull NSNotificationName)notificationName | ||
toStateIdentifier:(nonnull NSString *)identifier | ||
handle:(nonnull CDPHandleNotificationBlock)block; | ||
|
||
/// 将 identifier 对应状态 与 notificationName 对应的通知 解除状态同步 | ||
/// @param notificationName 要同步的广播通知名称 | ||
/// @param identifier 被同步的 对应 状态 唯一标识 | ||
- (void)unsyncNotificationName:(nonnull NSNotificationName)notificationName | ||
toStateIdentifier:(nonnull NSString *)identifier; | ||
|
||
|
||
@end | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,235 @@ | ||
// | ||
// CDPStateManager.m | ||
// stateManager | ||
// | ||
// Created by CDP on 2021/7/10. | ||
// | ||
|
||
#import "CDPStateManager.h" | ||
|
||
#import "CDPStateManagerObjectPool.h" | ||
#import "CDPStateManagerActionPool.h" | ||
#import "CDPStateManagerNotificationPool.h" | ||
|
||
#define CDPStateNotificationKeyPrefix @"CDPStateNotification_" | ||
|
||
@interface CDPStateManager () | ||
|
||
@property (nonatomic, strong) CDPStateManagerObjectPool *objectPool; //object储存池 | ||
|
||
@property (nonatomic, strong) CDPStateManagerActionPool *actionPool; //action储存池 | ||
|
||
@property (nonatomic, strong) CDPStateManagerNotificationPool *notificationPool; //notification相关储存池 | ||
|
||
@end | ||
|
||
@implementation CDPStateManager | ||
|
||
+ (instancetype)defaultManager { | ||
static CDPStateManager *manager; | ||
static dispatch_once_t once; | ||
dispatch_once(&once, ^{ | ||
manager = [[CDPStateManager alloc] init]; | ||
}); | ||
return manager; | ||
} | ||
- (void)dealloc { | ||
[[NSNotificationCenter defaultCenter] removeObserver:self]; | ||
} | ||
#pragma mark - 管理控件 | ||
//获取 identifier 对应状态的 object 管理池 | ||
- (NSHashTable *_Nonnull)getHashTableWithIdentifier:(nonnull NSString *)identifier { | ||
return [self.objectPool getHashTableWithIdentifier:identifier]; | ||
} | ||
//将 相关控件 添加进 identifier 对应 状态管理池 中 (控件释放后 内部会自动对其 移除, 不需要 主动移除) | ||
- (void)addObject:(id<CDPStateManagerProtocol>)object stateIdentifier:(NSString *)identifier { | ||
if ([object conformsToProtocol:@protocol(CDPStateManagerProtocol)]) { | ||
[self.objectPool addObject:object stateIdentifier:identifier]; | ||
} | ||
} | ||
//主动将 相关控件 从 identifier 对应 状态管理池 中移除 | ||
- (void)removeObject:(id<CDPStateManagerProtocol>)object stateIdentifier:(NSString *)identifier { | ||
if ([object conformsToProtocol:@protocol(CDPStateManagerProtocol)]) { | ||
[self.objectPool removeObject:object stateIdentifier:identifier]; | ||
} | ||
} | ||
//清空 identifier 对应 状态管理池 (慎用!!!) | ||
- (void)removeAllObjectsWithStateIdentifier:(NSString *)identifier { | ||
[self.objectPool removeAllObjectsWithStateIdentifier:identifier]; | ||
} | ||
|
||
#pragma mark - action | ||
|
||
//注册 identifier 对应状态 相关 action,如果该状态已注册 action,则自动替换 (状态 与 action 一一对应) | ||
- (void)registerActionWithStateIdentifier:(NSString *)identifier completion:(CDPHandleActionBlock)block { | ||
if ([identifier isKindOfClass:[NSString class]] && | ||
identifier.length > 0 && | ||
block) { | ||
NSDictionary *blockDic = @{@"block": [block copy]}; | ||
[self.actionPool saveActionConfigDic:blockDic identifier:identifier]; | ||
} | ||
} | ||
//移除 identifier 对应状态 相关 action | ||
- (void)removeActionWithStateIdentifier:(nonnull NSString *)identifier { | ||
[self.actionPool removeActionWithStateIdentifier:identifier]; | ||
} | ||
//执行 identifier 对应状态 相关 action,以改变状态 (必须先用 registerAction 添加再使用) | ||
- (void)actionWithParameters:(nullable NSDictionary *)parameters stateIdentifier:(nonnull NSString *)identifier { | ||
if ([identifier isKindOfClass:[NSString class]] && identifier.length > 0) { | ||
//获取actionBlock | ||
NSDictionary *blockDic = [self.actionPool getActionConfigDicWithIdentifier:identifier]; | ||
|
||
if (blockDic.allKeys.count == 0) { | ||
return; | ||
} | ||
CDPHandleActionBlock block = [blockDic objectForKey:@"block"]; | ||
|
||
//获取action处理后的数据 | ||
NSDictionary *completionDic = nil; | ||
if (block) { | ||
completionDic = block(parameters); | ||
} | ||
if ([completionDic isKindOfClass:[NSDictionary class]]) { | ||
NSString *notSync = [completionDic objectForKey:@"stateManagerNotSync"]; | ||
if ([notSync isKindOfClass:[NSString class]] && [notSync isEqualToString:@"1"]) { | ||
//不进行同步回调 | ||
return; | ||
} | ||
} | ||
//对该状态关联的管理控件发送回调 | ||
[self actionStateChangedWithDic:completionDic parameters:parameters identifier:identifier]; | ||
} | ||
} | ||
//发送action回调 | ||
- (void)actionStateChangedWithDic:(NSDictionary *)dic parameters:(NSDictionary *)parameters identifier:(NSString *)identifier { | ||
if ([identifier isKindOfClass:[NSString class]] && identifier.length > 0) { | ||
//获取对应状态的 控件管理池容器 | ||
NSHashTable *hashTable = [self.objectPool getHashTableWithIdentifier:identifier]; | ||
|
||
for (id object in hashTable) { | ||
//判断CDPStateManagerProtocol协议 | ||
if ([object conformsToProtocol:@protocol(CDPStateManagerProtocol)] && | ||
[object respondsToSelector:@selector(receiveStateActionWithDic:parameters:stateIdentifier:)]) { | ||
[object receiveStateActionWithDic:dic parameters:parameters stateIdentifier:identifier]; | ||
} | ||
} | ||
} | ||
} | ||
|
||
#pragma mark - 同步通知 | ||
|
||
//将 notificationName 对应的通知 与 identifier 对应状态 进行同步绑定,使该 状态 可以被 notification 进行状态同步 | ||
- (void)syncNotificationName:(nonnull NSNotificationName)notificationName | ||
toStateIdentifier:(nonnull NSString *)identifier | ||
handle:(nonnull CDPHandleNotificationBlock)block { | ||
if ([identifier isKindOfClass:[NSString class]] && | ||
identifier.length > 0 && | ||
[notificationName isKindOfClass:[NSString class]] && | ||
notificationName.length > 0 && | ||
block) { | ||
//监听该通知 | ||
if (![self.notificationPool.listenNotificationArr containsObject:notificationName]) { | ||
[self.notificationPool.listenNotificationArr addObject:notificationName]; | ||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotification:) name:notificationName object:nil]; | ||
} | ||
//将状态与通知绑定 | ||
[self.notificationPool addSyncStateIdentifier:identifier forNotificationName:notificationName]; | ||
//保存对应的block回调 | ||
NSDictionary *blockDic = @{@"block": [block copy]}; | ||
NSString *actionKey = [self getNotificationActionKeyWithStateIdentifier:identifier notificationName:notificationName]; | ||
[self.actionPool saveActionConfigDic:blockDic identifier:actionKey]; | ||
} | ||
} | ||
//将 identifier 对应状态 与 notificationName 对应的通知 解除状态同步 | ||
- (void)unsyncNotificationName:(nonnull NSNotificationName)notificationName toStateIdentifier:(nonnull NSString *)identifier { | ||
if ([identifier isKindOfClass:[NSString class]] && | ||
identifier.length > 0 && | ||
[notificationName isKindOfClass:[NSString class]] && | ||
notificationName.length > 0) { | ||
//解除绑定 | ||
[self.notificationPool removeSyncStateIdentifier:identifier forNotificationName:notificationName]; | ||
//移除对应block回调 | ||
NSString *actionKey = [self getNotificationActionKeyWithStateIdentifier:identifier notificationName:notificationName]; | ||
[self.actionPool removeActionWithStateIdentifier:actionKey]; | ||
|
||
//检查是否可移除监听通知 | ||
if ([self.notificationPool getAllStateIdentifierWithNotificationName:notificationName].count == 0 && | ||
[self.notificationPool.listenNotificationArr containsObject:notificationName]) { | ||
|
||
[self.notificationPool.listenNotificationArr removeObject:notificationName]; | ||
[[NSNotificationCenter defaultCenter] removeObserver:self name:notificationName object:nil]; | ||
} | ||
} | ||
} | ||
//收到通知进行处理并回调 | ||
- (void)receiveNotification:(NSNotification *)notification { | ||
if (notification && | ||
[notification.name isKindOfClass:[NSString class]] && | ||
notification.name.length > 0) { | ||
//获取所有绑定的自定义状态 | ||
NSArray *stateArr = [self.notificationPool getAllStateIdentifierWithNotificationName:notification.name]; | ||
for (NSString *identifier in stateArr) { | ||
//获取对应block | ||
NSString *actionKey = [self getNotificationActionKeyWithStateIdentifier:identifier notificationName:notification.name]; | ||
NSDictionary *blockDic = [self.actionPool getActionConfigDicWithIdentifier:actionKey]; | ||
if (blockDic.allKeys.count == 0) { | ||
continue; | ||
} | ||
CDPHandleNotificationBlock block = [blockDic objectForKey:@"block"]; | ||
//获取action处理后的数据 | ||
NSDictionary *completionDic = nil; | ||
if (block) { | ||
completionDic = block(notification); | ||
} | ||
if ([completionDic isKindOfClass:[NSDictionary class]]) { | ||
NSString *notSync = [completionDic objectForKey:@"stateManagerNotSync"]; | ||
if ([notSync isKindOfClass:[NSString class]] && [notSync isEqualToString:@"1"]) { | ||
//不进行同步回调 | ||
return; | ||
} | ||
} | ||
//对该自定义状态所管理控件发送同步回调 | ||
[self syncNotificationWithDic:completionDic notification:notification identifier:identifier]; | ||
} | ||
} | ||
} | ||
//发送notification通知同步回调 | ||
- (void)syncNotificationWithDic:(NSDictionary *)dic notification:(NSNotification *)notification identifier:(NSString *)identifier { | ||
if ([identifier isKindOfClass:[NSString class]] && identifier.length > 0) { | ||
//获取对应状态的 控件管理池容器 | ||
NSHashTable *hashTable = [self.objectPool getHashTableWithIdentifier:identifier]; | ||
|
||
for (id object in hashTable) { | ||
//判断CDPStateManagerProtocol协议 | ||
if ([object conformsToProtocol:@protocol(CDPStateManagerProtocol)] && | ||
[object respondsToSelector:@selector(receiveStateNotificationSyncWithDic:notification:stateIdentifier:)]) { | ||
[object receiveStateNotificationSyncWithDic:dic notification:notification stateIdentifier:identifier]; | ||
} | ||
} | ||
} | ||
} | ||
//获取对应状态处理notification数据的block的key | ||
- (NSString *)getNotificationActionKeyWithStateIdentifier:(nonnull NSString *)identifier notificationName:(nonnull NSNotificationName)notificationName { | ||
return [NSString stringWithFormat:@"%@%@_%@", CDPStateNotificationKeyPrefix, notificationName, identifier]; | ||
} | ||
#pragma mark - getter | ||
- (CDPStateManagerObjectPool *)objectPool { | ||
if (_objectPool == nil) { | ||
_objectPool = [CDPStateManagerObjectPool new]; | ||
} | ||
return _objectPool; | ||
} | ||
- (CDPStateManagerActionPool *)actionPool { | ||
if (_actionPool == nil) { | ||
_actionPool = [CDPStateManagerActionPool new]; | ||
} | ||
return _actionPool; | ||
} | ||
- (CDPStateManagerNotificationPool *)notificationPool { | ||
if (_notificationPool == nil) { | ||
_notificationPool = [CDPStateManagerNotificationPool new]; | ||
} | ||
return _notificationPool; | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// | ||
// CDPStateManagerProtocol.h | ||
// stateManager | ||
// | ||
// Created by CDP on 2021/7/10. | ||
// 涉及状态管理的 object 需要遵循的协议 ,并通过 CDPStateManager 管理使用 | ||
|
||
@protocol CDPStateManagerProtocol <NSObject> | ||
|
||
@optional | ||
|
||
/// 收到 状态改变 回调,可进行改变后的逻辑处理 | ||
/// @param dic 执行 action 时通过 block 回调的用来 同步状态数据的 字典 | ||
/// @param parameters 执行 action 时的 传参,可与 当前数据进行匹配 是否对应 | ||
/// @param identifier 对应 状态 唯一标识 | ||
- (void)receiveStateActionWithDic:(NSDictionary *)dic | ||
parameters:(NSDictionary *)parameters | ||
stateIdentifier:(NSString *)identifier; | ||
|
||
/// 收到 通知 的同步回调,可进行对应逻辑处理 | ||
/// @param dic 对收到的 notification 用 block 回调处理后的 同步数据 | ||
/// @param notification 收到的 notification 通知 | ||
/// @param identifier 对应 状态 唯一标识 | ||
- (void)receiveStateNotificationSyncWithDic:(NSDictionary *)dic | ||
notification:(NSNotification *)notification | ||
stateIdentifier:(NSString *)identifier; | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// | ||
// CDPStateManagerActionPool.h | ||
// stateManager | ||
// | ||
// Created by CDP on 2021/7/10. | ||
// action 储存池 | ||
|
||
#import <Foundation/Foundation.h> | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@interface CDPStateManagerActionPool : NSObject | ||
|
||
/// 保存状态对应action | ||
/// @param configDic 对应action相关设置 | ||
/// @param identifier 对应 状态 唯一标识 | ||
- (void)saveActionConfigDic:(NSDictionary *)configDic identifier:(NSString *)identifier; | ||
|
||
/// 移除 identifier 对应状态 相关 action | ||
/// @param identifier 对应 状态 唯一标识 | ||
- (void)removeActionWithStateIdentifier:(NSString *)identifier; | ||
|
||
/// 获取状态对应action的相关设置 | ||
/// @param identifier 对应 状态 唯一标识 | ||
- (NSDictionary *)getActionConfigDicWithIdentifier:(NSString *)identifier; | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
Oops, something went wrong.