美文网首页
iOS NSTimer 单利做法 解决循环引用

iOS NSTimer 单利做法 解决循环引用

作者: yuezishenyou | 来源:发表于2019-01-23 16:12 被阅读0次
概述

NSTimer 的用途很多,轮播、定时任务等都会用到,但是计时器很容易发生循环引用问题。

这里讲到的是老师写的一个单利计时器
解决循环引用,并且整个项目只有一个计时器,很不错。

正文

核心代码块

TimerManager.h 文件

#import <Foundation/Foundation.h>

@interface TimerItem : NSObject

@property (nonatomic,copy) void(^timercb)(void);
@property (nonatomic,copy) NSString *name;
@property (nonatomic,assign) NSInteger timerSpace;
@property (nonatomic,assign) BOOL isValid;

@end


//*************** *******************/
@interface TimerManager : NSObject

+ (instancetype)manager;

- (void)addTimerWithName:(NSString *)name timerSpace:(NSInteger)timerSpace timercb:(void(^)(void))timercb;

- (void)deleteTimerWithName:(NSString *)name;

- (void)stopTimerWithName:(NSString *)name;

- (void)validTimerWithName:(NSString *)name;

- (void)modifyTimerWithName:(NSString *)name toTimerSpace:(NSInteger)timerSpace;

- (BOOL)isTimerValid:(NSString *)name;

- (void)stopAllTimers;

- (void)validTimers;

@end

TimerManager.m 文件

#import "TimerManager.h"


@implementation TimerItem

@end


@implementation TimerManager
{
    NSMutableArray *_timerArray;
    NSTimer *_timer;
    NSInteger count;
}
+ (instancetype)manager
{
    static TimerManager *_manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (_manager == nil) {
            _manager = [[TimerManager alloc]init];
        }
    });
    return _manager;
}

- (instancetype)init
{
    if (self = [super init])
    {
        _timer = [NSTimer scheduledTimerWithTimeInterval:1.0/60 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
        [[NSRunLoop currentRunLoop]addTimer:_timer forMode:NSRunLoopCommonModes];
        count = 0;
        _timerArray = [[NSMutableArray alloc]init];
    }
    return self;
}

- (void)timerAction
{
    count ++;
    for (TimerItem *item in _timerArray)
    {
        if (item.isValid && count % item.timerSpace == 0)
        {
            item.timercb();
        }
    }
}







// -----------------------------------------------
// MARK - methods
// -----------------------------------------------

- (void)addTimerWithName:(NSString *)name timerSpace:(NSInteger)timerSpace timercb:(void (^)(void))timercb
{
    for (TimerItem *item in _timerArray)
    {
        if ([item.name isEqualToString:name]) {
            return;
        }
    }
    
    TimerItem *item = [[TimerItem alloc]init];
    item.name = name;
    item.timerSpace = timerSpace;
    item.timercb = timercb;
    item.isValid = YES;
    [_timerArray addObject:item];
    
}



- (void)deleteTimerWithName:(NSString *)name
{
    for (NSInteger i = _timerArray.count - 1; i >= 0; i--)
    {
        TimerItem *item = _timerArray[i];
        if ([item.name isEqualToString:name])
        {
            [_timerArray removeObject:item];
        }
    }
}

- (void)stopTimerWithName:(NSString *)name
{
    for (TimerItem *item in _timerArray)
    {
        if ([item.name isEqualToString:name])
        {
            item.isValid = NO;
        }
    }
}

- (void)validTimerWithName:(NSString *)name
{
    for (TimerItem *item in _timerArray)
    {
        if ([item.name isEqualToString:name])
        {
            item.isValid = YES;
        }
    }
}

- (void)modifyTimerWithName:(NSString *)name toTimerSpace:(NSInteger)timerSpace
{
    for (TimerItem *item in _timerArray)
    {
        if ([item.name isEqualToString:name])
        {
            item.timerSpace = timerSpace;
        }
    }
}

- (BOOL)isTimerValid:(NSString *)name
{
    for (TimerItem *item in _timerArray)
    {
        if ([item.name isEqualToString:name])
        {
            return item.isValid;
        }
    }
    return NO;
}

- (void)stopAllTimers
{
    [_timer setFireDate:[NSDate distantFuture]];
}

- (void)validTimers
{
    [_timer setFireDate:[NSDate distantPast]];
}



@end

相关文章

网友评论

      本文标题:iOS NSTimer 单利做法 解决循环引用

      本文链接:https://www.haomeiwen.com/subject/hhfsjqtx.html