美文网首页
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