1、设计思路
1.1、系统类NSTimer做一次性计时使用还可以,如果需要暂停继续的话就不太灵活了;
1.2、通过dispatch_after延时执行函数,配套循环语句算法实现间隔n秒触发一次调用;
1.3、设计一个状态属性,对当前的状态进行管理,如准备、暂停、继续、开始、结束等;
2、相关属性与方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | // // SATimer.h // Test // // Created by 余西安 on 16/8/11. // Copyright ? 2016年 Sian. All rights reserved. // #import <foundation /Foundation.h> // 定时器状态 typedef NS_ENUM(NSInteger, SATimerStatus){ SATimerStatusReady = 0, // 准备 SATimerStatusRunning, // 正在运行 SATimerStatusPaused, // 已暂停,可继续计时 SATimerStatusStoped // 已停止,只能重新开始 }; typedef void (^SATimerBlock)(NSUInteger remainCount); @interface SATimer : NSObject // 间隔时间 @property (nonatomic, assign) NSTimeInterval interval; // 重复次数 @property (nonatomic, assign) NSUInteger repeatCount; @property (nonatomic, assign) SATimerStatus status; + (instancetype)timeWithInterval:(NSTimeInterval)ti repeatCount:(NSInteger)count block:(SATimerBlock)block; - (instancetype)initWithInterval:(NSTimeInterval)ti repeatCount:(NSInteger)count block:(SATimerBlock)block; // 开始(重新开始) - (void)start; // 暂停(可继续) - (void)pause; // 继续 - (void)continues; // 停止(不可继续,只能重新开始) - (void)stop; @end </foundation> |
3、实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | // // SATimer.m // Test // // Created by 余西安 on 16/8/11. // Copyright ? 2016年 Sian. All rights reserved. // #import "SATimer.h" @interface SATimer () @property (nonatomic, assign) NSInteger currentCount; @property (nonatomic, copy) SATimerBlock block; @end @implementation SATimer + (instancetype)timeWithInterval:(NSTimeInterval)ti repeatCount:(NSInteger)count block:(SATimerBlock)block { return [[self alloc] initWithInterval:ti repeatCount:count block:block]; } - (instancetype)initWithInterval:(NSTimeInterval)ti repeatCount:(NSInteger)count block:(SATimerBlock)block { if (self = [super init]){ self.interval = ti; self.repeatCount = count; self.currentCount = count; self.block = block; } return self; } - (void)repeatMethod { if (self.currentCount <= 0 || self.status != SATimerStatusRunning) return; self.currentCount--; if (self.block) self.block(self.currentCount); dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (self.interval * NSEC_PER_SEC)); dispatch_after(time, dispatch_get_main_queue(), ^{ [self repeatMethod]; }); } - (void)start { if (self.status == SATimerStatusRunning) return; self.currentCount = self.repeatCount; self.status = SATimerStatusRunning; [self repeatMethod]; } - (void)continues { if (self.status == SATimerStatusRunning || self.currentCount == 0) return; self.status = SATimerStatusRunning; [self repeatMethod]; } - (void)pause { self.status = SATimerStatusPaused; } - (void)stop { self.status = SATimerStatusStoped; self.currentCount = 0; } - (void)setCurrentCount:(NSInteger)currentCount { self->_currentCount = currentCount; if (currentCount == 0) self.status = SATimerStatusStoped; } - (void)dealloc { NSLog(@"%@---dealloc", self); } @end |