This commit is contained in:
DDIsFriend
2023-08-18 17:28:57 +08:00
commit f0e8a1709d
4282 changed files with 192396 additions and 0 deletions

View File

@@ -0,0 +1,83 @@
//
// DDTimerManager.h
// DDToolsKit_Private
// Created by DDIsFriend on 2022/7/29.
#import <Foundation/Foundation.h>
#import "DDTimerObject.h"
NS_ASSUME_NONNULL_BEGIN
#define TIME_FOREVER (~0ull)
@interface DDTimerManager : NSObject
/**
*return a static instance.
*/
+ (instancetype)dd_shareManager;
- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;
/**
*add a timerObject to the timerManager.
*@param timerName a timerName.
*@param timeInterval The nanosecond interval for the timer.
*@param repeatCount if repeatCount is 0, the timer will cycle always.
*@param delayTimeInterval you can set Time_Forever , then manual wake up timer by invoked 'makeTimerActivateNamed' .
*@param timerBlock what to do in this timer.
*@param completionBlock this block invoked by adding timer success.
*@warning completionBlock is invoked async.
*/
- (void)dd_addTimerWithName:(NSString *)timerName timeInterval:(NSTimeInterval)timeInterval repeatCount:(NSUInteger)repeatCount delay:(NSTimeInterval)delayTimeInterval timerBlock:(nullable void(^)(DDTimerManager * _timerManager,DDTimerObject *_Nullable timerObject, NSUInteger timerObjectIndex))timerBlock completionBlock:(nullable void(^)(void))completionBlock;
/**
* the timerObject is weather activate now.
*@param timerName a timerName.
*/
- (DDTimerRunState)dd_runStateAboutTimerObjectNamed:(NSString *)timerName;
/**
*wheather timerObject is contained in the timerManager.
*@param timerName a timerObject name.
*/
- (BOOL)dd_containTimerNamed:(NSString *)timerName;
/**
*manual invoke timer activate.
*@param timerName a timerObject name.
*/
- (void)dd_makeTimerActivateNamed:(NSString *)timerName;
/**
*manual invoke timer suspend.
*@param timerName a timerObject name.
*/
- (void)dd_makeTimerSuspendNamed:(NSString *)timerName;
/**
*manual invoke timer resume.
*@param timerName a timerObject name.
*/
- (void)dd_makeTimerResumeNamed:(NSString *)timerName;
/**
*remove a timerObject from the timerManager.
*@param timerObject a timerObject.
*/
- (void)dd_removeTimer:(DDTimerObject *)timerObject;
/**
*remove a timerObject from the timerManager.
*@param timerName a timerObject name.
*/
- (void)dd_removeTimerNamed:(NSString *)timerName;
/**
* remove all timers.
*/
- (void)dd_removeAllTimer;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,274 @@
//
// DDTimerManager.m
// DDToolsKit_Private
// Created by DDIsFriend on 2022/7/29.
#import "DDTimerManager.h"
typedef NSString * DDTimerManagerOperate NS_STRING_ENUM;
DDTimerManagerOperate const DDTimerManagerOperateAddSuccess = @"定时器添加成功";
DDTimerManagerOperate const DDTimerManagerOperateAddErrorOfContained = @"定时器添加失败,原因:已添加";
DDTimerManagerOperate const DDTimerManagerOperateRemoveSuccess = @"定时器移除成功";
DDTimerManagerOperate const DDTimerManagerOperateRemoveErrorOfNotContained = @"定时器移除失败,原因:未包含";
DDTimerManagerOperate const DDTimerManagerOperateTimerNotFind = @"未找到定时器";
@interface DDTimerManager ()
@property (nonatomic, strong)NSPointerArray *timers;
@property (nonatomic, strong)dispatch_queue_t timerManagerQueue;
@end
@implementation DDTimerManager
+ (instancetype)dd_shareManager{
static DDTimerManager *_manager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_manager = [[self alloc] initWithSuper];
});
return _manager;
}
- (instancetype)initWithSuper{
self = [super init];
if (!self) return nil;
return self;
}
- (instancetype)init{
@throw [NSException exceptionWithName:NSGenericException reason:@"init unavailable, use 'dd_shareManager' instead" userInfo:nil];
return nil;
}
- (void)dd_addTimerWithName:(NSString *)timerName timeInterval:(NSTimeInterval)timeInterval repeatCount:(NSUInteger)repeatCount delay:(NSTimeInterval)delayTimeInterval timerBlock:(nullable void(^)(DDTimerManager * _timerManager,DDTimerObject *_Nullable timerObject, NSUInteger timerObjectIndex))timerBlock completionBlock:(nullable void(^)(void))completionBlock{
dispatch_async(self.timerManagerQueue, ^{
BOOL addSuccess = [self dd_addTimerWithName:timerName timeInterval:timeInterval repeatCount:repeatCount delay:delayTimeInterval timerBlock:timerBlock];
if (addSuccess) {
@try {
if (completionBlock) {
completionBlock();
}
} @catch (NSException *exception) {
NSLog(@"%@",exception);
} @finally {
}
}else{
NSLog(@"name = %@ , %@",timerName,DDTimerManagerOperateAddErrorOfContained);
}
});
}
- (BOOL)dd_addTimerWithName:(NSString *)timerName timeInterval:(NSTimeInterval)timeInterval repeatCount:(NSUInteger)repeatCount delay:(NSTimeInterval)delayTimeInterval timerBlock:(nullable void(^)(DDTimerManager * _timerManager,DDTimerObject *_Nullable timerObject, NSUInteger timerObjectIndex))timerBlock{
__block BOOL addTimerSuccess = NO;
__block BOOL isAddedSameNameTimerBefore = NO;
[self.timers.allObjects enumerateObjectsUsingBlock:^(DDTimerObject *_Nonnull timerObject, NSUInteger idx, BOOL * _Nonnull stop) {
if ([timerObject.name isEqualToString:timerName]) {
isAddedSameNameTimerBefore = YES;
*stop = YES;
}
}];
if (isAddedSameNameTimerBefore) {
NSLog(@"name = '%@' , %@",timerName,DDTimerManagerOperateAddErrorOfContained);
addTimerSuccess = NO;
return addTimerSuccess;
}
__weak typeof(self) weakSelf = self;
DDTimerObject *timerObject = [DDTimerObject dd_timerObjectWithName:timerName timeInterval:timeInterval repeatCount:repeatCount timerBlock:^(DDTimerObject * _Nullable timerObject) {
__strong typeof(weakSelf) strongSelf = weakSelf;
if (timerBlock) {
timerBlock(strongSelf,timerObject,strongSelf.timers.count);
}
} completionHandler:^(DDTimerObject * _Nullable timerObject) {
__strong typeof(weakSelf) strongSelf = weakSelf;
/// timer will be removed when action completed.
[strongSelf dd_removeTimerNamed:timerObject.name];
}];
[self.timers addPointer:(__bridge void * _Nullable)timerObject];
NSLog(@"name = '%@' , %@",timerObject.name,DDTimerManagerOperateAddSuccess);
/// make timer activate.
dispatch_after(dispatch_time((delayTimeInterval == TIME_FOREVER) ? DISPATCH_TIME_FOREVER : DISPATCH_TIME_NOW, (int64_t)(delayTimeInterval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[timerObject dd_activateTimerObject];
});
addTimerSuccess = YES;
return addTimerSuccess;
}
- (DDTimerRunState)dd_runStateAboutTimerObjectNamed:(NSString *)timerName{
DDTimerObject *_timerObject = nil;
for (DDTimerObject *timerObject in self.timers.allObjects){
if ([timerObject.name isEqualToString:timerName]) {
_timerObject = timerObject;
break;
}
}
if (_timerObject == nil) {
NSLog(@"name = %@ , %@",timerName,DDTimerManagerOperateTimerNotFind);
return NO;
}
return _timerObject.runState;
}
- (BOOL)dd_containTimerNamed:(NSString *)timerName{
BOOL isAddedSameNameTimerBefore = NO;
for (DDTimerObject *timerObject in self.timers.allObjects){
if ([timerObject.name isEqualToString:timerName]) {
isAddedSameNameTimerBefore = YES;
break;
}
}
return isAddedSameNameTimerBefore;
}
- (void)dd_makeTimerActivateNamed:(NSString *)timerName{
DDTimerObject *_timerObject;
for (DDTimerObject *timerObject in self.timers.allObjects){
if ([timerObject.name isEqualToString:timerName]) {
_timerObject = timerObject;
break;
}
}
if (_timerObject != nil) {
[_timerObject dd_activateTimerObject];
}else{
NSLog(@"name = %@ , %@",timerName,DDTimerManagerOperateTimerNotFind);
}
}
- (void)dd_makeTimerSuspendNamed:(NSString *)timerName{
DDTimerObject *_timerObject;
for (DDTimerObject *timerObject in self.timers.allObjects){
if ([timerObject.name isEqualToString:timerName]) {
_timerObject = timerObject;
break;
}
}
if (_timerObject != nil) {
[_timerObject dd_suspendTimerObject];
}else{
NSLog(@"name = %@ , %@",timerName,DDTimerManagerOperateTimerNotFind);
}
}
- (void)dd_makeTimerResumeNamed:(NSString *)timerName{
DDTimerObject *_timerObject;
for (DDTimerObject *timerObject in self.timers.allObjects){
if ([timerObject.name isEqualToString:timerName]) {
_timerObject = timerObject;
break;
}
}
if (_timerObject != nil) {
[_timerObject dd_resumeTimerObject];
}else{
NSLog(@"name = %@ , %@",timerName,DDTimerManagerOperateTimerNotFind);
}
}
- (void)dd_removeTimer:(DDTimerObject *)timerObject{
dispatch_async(self.timerManagerQueue, ^{
[self removeTimerWithTimerObject:timerObject timerName:nil];
});
}
- (void)dd_removeTimerNamed:(NSString *)timerName{
dispatch_async(self.timerManagerQueue, ^{
[self removeTimerWithTimerObject:nil timerName:timerName];
});
}
- (void)removeTimerWithTimerObject:(nullable DDTimerObject *)timerObject timerName:(nullable NSString *)timerName{
///if timerObject is non-nulable, timerName is invalid.
if (self.timers == 0) return;
NSMutableArray *removeIndexs = [NSMutableArray array];
[self.timers.allObjects enumerateObjectsUsingBlock:^(DDTimerObject *_Nonnull _timerObject, NSUInteger idx, BOOL * _Nonnull stop) {
if ((timerObject != nil && timerObject == _timerObject) || (timerName != nil && [timerName isEqualToString:_timerObject.name])) {
[removeIndexs addObject:@(idx)];
*stop = YES;
}
}];
if (removeIndexs.count > 0) {
for (NSNumber *indexNum in removeIndexs){
DDTimerObject *timerObject = [self.timers pointerAtIndex:[indexNum integerValue]];
[timerObject dd_cancelTimerObject];
[self.timers removePointerAtIndex:[indexNum integerValue]];
timerObject = nil;
}
if (timerName != nil) {
NSLog(@"name = '%@' , %@",timerName,DDTimerManagerOperateRemoveSuccess);
}
[self logLeftTimer];
}else{
if (timerObject != nil) {
NSLog(@"timerObject = %@ , %@",timerObject,DDTimerManagerOperateRemoveErrorOfNotContained);
}else if (timerName != nil){
NSLog(@"name = %@ , %@",timerName,DDTimerManagerOperateRemoveErrorOfNotContained);
}
}
[removeIndexs removeAllObjects];
removeIndexs = nil;
}
- (void)dd_removeAllTimer{
if (self.timers.count == 0) return;
dispatch_async(self.timerManagerQueue, ^{
NSUInteger timersCount = self.timers.count;
for (NSUInteger i = 0; i < timersCount; i++) {
@autoreleasepool {
DDTimerObject *timerObject = [self.timers pointerAtIndex:i];
[timerObject dd_cancelTimerObject];
[self.timers replacePointerAtIndex:i withPointer:NULL];
timerObject = nil;
}
}
[self.timers compact];
[self logLeftTimer];
});
}
- (void)logLeftTimer{
if (self.timers.count == 0) return NSLog(@"DDTimerManager剩余定时器数量为0");
[self.timers.allObjects enumerateObjectsUsingBlock:^(DDTimerObject *_Nonnull _timerObject, NSUInteger idx, BOOL * _Nonnull stop) {
NSLog(@"当前剩余的定时器name = %@",_timerObject.name);
}];
}
#pragma mark -- <lazy>
- (NSPointerArray *)timers{
if (!_timers) {
_timers = [NSPointerArray strongObjectsPointerArray];
}
return _timers;
}
- (dispatch_queue_t)timerManagerQueue{
if (!_timerManagerQueue) {
_timerManagerQueue = dispatch_queue_create("timerManager_timerManagerQueue", DISPATCH_QUEUE_SERIAL);
}
return _timerManagerQueue;
}
@end

View File

@@ -0,0 +1,55 @@
//
// DDTimerObject.h
// DDToolsKit_Private
// Created by DDIsFriend on 2022/7/29.
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSUInteger, DDTimerRunState) {
DDTimerRunStateNotActivate,
DDTimerRunStateActivate,
DDTimerRunStateSuspend,
};
@interface DDTimerObject : NSObject
@property (nonatomic, copy, readonly)NSString *name;
@property (nonatomic, assign, readonly)NSTimeInterval timeInterval;
@property (nonatomic, assign, readonly)BOOL isActivate;
@property (nonatomic, assign, readonly)DDTimerRunState runState;
/**
*return a timerObject with dispatch_source_t.
*@param name timer's name is required.
*@param timerInterval The nanosecond interval for the timer.
*@param repeatCount if repeatCount is 0, the timer will cycle always.
*@param timerBlock what to do in this timer.
*/
+ (DDTimerObject *)dd_timerObjectWithName:(NSString *)name timeInterval:(NSTimeInterval)timerInterval repeatCount:(NSInteger)repeatCount timerBlock:(nullable void(^)(DDTimerObject *_Nullable timerObject))timerBlock completionHandler:(nullable void(^)(DDTimerObject *_Nullable timerObject))completionHandler;
/**
* the timerObject is whether activate now.
*/
- (DDTimerRunState)dd_timerRunState;
/**
* activate timer that timer can run.
*/
- (void)dd_activateTimerObject;
/**
* cancel dispatch_source_t.
*/
- (void)dd_cancelTimerObject;
/**
* suspend timer.
*/
- (void)dd_suspendTimerObject;
/**
* resume timer.
*/
- (void)dd_resumeTimerObject;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,104 @@
//
// DDTimerObject.m
// DDToolsKit_Private
// Created by DDIsFriend on 2022/7/29.
#import "DDTimerObject.h"
typedef void(^TimerEventHandler)(DDTimerObject *_Nullable timerObject);
@interface DDTimerObject ()
@property (nonatomic, strong, nullable)dispatch_source_t timer;
@property (nonatomic, strong) dispatch_queue_t timerQueue;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSTimeInterval timeInterval;
@property (nonatomic, assign) NSUInteger repeatCount;
@property (nonatomic, assign, readwrite) DDTimerRunState runState;
@end
@implementation DDTimerObject
+ (DDTimerObject *)dd_timerObjectWithName:(NSString *)name timeInterval:(NSTimeInterval)timerInterval repeatCount:(NSInteger)repeatCount timerBlock:(nullable void(^)(DDTimerObject *_Nullable timerObject))timerBlock completionHandler:(nullable void(^)(DDTimerObject *_Nullable timerObject))completionHandler{
DDTimerObject *timerObject = [[DDTimerObject alloc] init];
timerObject.name = name;
timerObject.timeInterval = timerInterval;
[timerObject objectAddTimer:timerInterval repeatCount:repeatCount timerBlock:timerBlock completionHandler:completionHandler];
return timerObject;
}
- (void)objectAddTimer:(NSTimeInterval)timerInterval repeatCount:(NSInteger)repeatCount timerBlock:(void(^)(DDTimerObject *_Nullable timerObject))timerBlock completionHandler:(nullable void(^)(DDTimerObject *_Nullable timerObject))completionHandler{
self.repeatCount = 0;
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.timerQueue);
dispatch_source_set_timer(self.timer, DISPATCH_TIME_NOW, timerInterval * NSEC_PER_SEC, 0);
__weak typeof(self) weakSelf = self;
dispatch_source_set_event_handler(self.timer, ^{
__strong typeof(weakSelf) strongSelf = weakSelf;
///run
if (timerBlock) {
timerBlock(strongSelf);
}
if ((repeatCount > 0 && strongSelf.repeatCount >= repeatCount)) {
///stop
if (completionHandler) {
completionHandler(strongSelf);
}
return;
}
strongSelf.repeatCount++;
});
self.runState = DDTimerRunStateNotActivate;
}
- (DDTimerRunState)dd_timerRunState{
return self.runState;
}
- (void)dd_activateTimerObject{
if (self.timer == nil) return;
if (self.runState == DDTimerRunStateSuspend) return;
if (self.runState == DDTimerRunStateActivate) return;
dispatch_activate(self.timer);
self.runState = DDTimerRunStateActivate;
}
- (void)dd_cancelTimerObject{
if (self.timer == nil) return;
if (self.runState == DDTimerRunStateNotActivate) return;
dispatch_cancel(self.timer);
NSLog(@"名为 %@ 的定时器取消了",self.name);
self.timer = nil;
self.runState = DDTimerRunStateNotActivate;
}
- (void)dd_suspendTimerObject{
if (self.timer == nil) return;
if (self.runState == DDTimerRunStateNotActivate) return;
if (self.runState == DDTimerRunStateSuspend) return;
dispatch_suspend(self.timer);
NSLog(@"名为 %@ 的定时器暂停了",self.name);
self.runState = DDTimerRunStateSuspend;
}
- (void)dd_resumeTimerObject{
if (self.timer == nil) return;
if (self.runState == DDTimerRunStateActivate) return;
dispatch_resume(self.timer);
NSLog(@"名为 %@ 的定时器恢复运行了",self.name);
self.runState = DDTimerRunStateActivate;
}
#pragma mark -- lazy
- (dispatch_queue_t)timerQueue{
if (!_timerQueue) {
_timerQueue = dispatch_queue_create("timerObject_queue", DISPATCH_QUEUE_CONCURRENT);
}
return _timerQueue;
}
@end

19
Pods/DDTimerKit_Private/LICENSE generated Normal file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2023 DDIsFriend <DDIsFriend@163.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

29
Pods/DDTimerKit_Private/README.md generated Normal file
View File

@@ -0,0 +1,29 @@
# DDTimerKit_Private
[![CI Status](https://img.shields.io/travis/DDIsFriend/DDTimerKit_Private.svg?style=flat)](https://travis-ci.org/DDIsFriend/DDTimerKit_Private)
[![Version](https://img.shields.io/cocoapods/v/DDTimerKit_Private.svg?style=flat)](https://cocoapods.org/pods/DDTimerKit_Private)
[![License](https://img.shields.io/cocoapods/l/DDTimerKit_Private.svg?style=flat)](https://cocoapods.org/pods/DDTimerKit_Private)
[![Platform](https://img.shields.io/cocoapods/p/DDTimerKit_Private.svg?style=flat)](https://cocoapods.org/pods/DDTimerKit_Private)
## Example
To run the example project, clone the repo, and run `pod install` from the Example directory first.
## Requirements
## Installation
DDTimerKit_Private is available through [CocoaPods](https://cocoapods.org). To install
it, simply add the following line to your Podfile:
```ruby
pod 'DDTimerKit_Private'
```
## Author
DDIsFriend, DDIsFriend@163.com
## License
DDTimerKit_Private is available under the MIT license. See the LICENSE file for more info.