iOS-简单易用的GCD计时器

前言

  很久没更新文章了,在掘金第一次发文章,仍是给本身立一个flag每周至少更新一篇文章,可能文章的质量还不是很如意,但愿经过写文章来提升本身文笔,以及记录本身学习中的遇到的问题解决方案。
  在学习iOS过程当中,想定你们对于定时器都不陌生,在平常开发中总会碰到须要计时器的功能,常见的定时器有NSTimer、GCD、CADisplayLink。网上也有不少的教程介绍三者的区别,今天主要讲的是GCD这种方式使用以及封装。git

三者归纳区别

优势 缺点
NSTimer 使用简单 受Runloop影响会致使计时不精准
CADisplayLink 精度高      CPU负载的时候会影响触发事件,且触发事件大于触发间隔会致使掉帧现象。
GCD 较精准 代码较多,基本不受其余影响

总结:NSTimer和CADisplayLink易受影响,而GCD虽然代码多,可是可控性很是强。github

GCD

/** 获取一个全局的线程来运行计时器*/
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
/** 建立一个计时器*/
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
/** 设置计时器, 这里是每10毫秒执行一次*/
dispatch_source_set_timer(timer, dispatch_walltime(nil, 0), 10*NSEC_PER_MSEC, 0);
/** 设置计时器的里操做事件*/
dispatch_source_set_event_handler(timer, ^{
	//do you want....
});
复制代码
开启、继续已暂停的定时器
dispatch_resume(timer);
复制代码
暂停定时器
/** 挂起的时候注意,屡次暂停的操做会致使线程锁的现象,即多少次暂停,
*   对应多少次的继续操做,即dispatch_suspend和dispatch_resume
*   是成对出现的,计时器才会继续工做。
*/
dispatch_suspend(timer);
复制代码
结束定时器
dispatch_source_cancel(timer);
复制代码

构思封装

写代码以前构思好功能模块以及会遇到的问题的解决方案、代码逻辑,再来下手写代码,会有事半功倍的效果。
  • 必然包含开始、暂停、继续、中止、重置功能
  • 时间计算过程当中因浮点数计算会丢失精度,计算过程应采用NSDecimal
  • 时间转换考虑到精度以及便利性,采用系统的时间转换方法,时区置为GMT
  • 因为APP进入后台,若未开启后台任务的开关,计时器将会中止,再次进入APP又会继续,故采用监听app状态的方式记录APP进入后台与前台的时间戳,并与截止时间相比,是否继续计时仍是结束计时并回调。
  • 计时器返回的结果若采用字符串则还需处理,故使用了一个时间类来把结果返回,能够进行自定义操做
  • 倒计时的结果返回和结束通知采用闭包形式

部分代码

/** app进入后台*/
- (void)appDidEnterBackground{
    [self suspend];
    NSDate *date = [[NSDate alloc] init];
    NSDateFormatter *format = [[NSDateFormatter alloc] init];
    format.dateFormat = @"yyyy-MM-dd HH:mm:ss:SSS";
    self.appDidEnterBackgroundTime = [date timeIntervalSince1970];
}

/** app进入前台*/
- (void)appDidEnterForeground{
    NSDate *date = [[NSDate alloc] init];
    NSDateFormatter *format = [[NSDateFormatter alloc] init];
    format.dateFormat = @"yyyy-MM-dd HH:mm:ss";
    self.appDidEnterForegroundTime = [date timeIntervalSince1970];
    [self reCalculateMinder];
}
复制代码
/** 不失精度加减乘除计算结果*/

- (NSDecimalNumber *)value: (NSTimeInterval)value 
                byOpration: (OMDecimalOprationType)byOpration       
                 percision:  (NSInteger)percision 
                withValue: (NSTimeInterval)withValue{

    NSDecimalNumber *number = [self numberValueWithString: value];
    NSDecimalNumber *withNumber = [self numberValueWithString: withValue];  
    NSDecimalNumberHandler *handler = [NSDecimalNumberHandler  decimalNumberHandlerWithRoundingMode: NSRoundPlain  scale: percision raiseOnExactness: NO  raiseOnOverflow: NO  raiseOnUnderflow: NO  raiseOnDivideByZero: YES];

switch (byOpration) {
    case  OMDecimalOprationTypeAdd:
      return [number decimalNumberByAdding: withNumber withBehavior:handler];
      break;
    case  OMDecimalOprationTypeSubtract:
      return [number decimalNumberBySubtracting: withNumber withBehavior: handler];
      break;
   case  OMDecimalOprationTypeDivide:
      return [number decimalNumberByDividingBy: withNumber withBehavior: handler];
      break;
  case  OMDecimalOprationTypeMultiple:
      return [number decimalNumberByMultiplyingBy: withNumber withBehavior: handler];
      break;
  default:
      break;
      return nil;
}
复制代码
@property (nonatomic, strong) OMTimer *timer;
复制代码
self.timer = [[OMTimer alloc] init];
self.timer.timerInterval = 30;
self.timer.precision = 100;
self.timer.isAscend = NO;
self.timer.progressBlock = ^(OMTime *progress) {
     NSLog(@"%@:%@:%@:%@", progress.hour, progress.minute, progress.second, progress.millisecond;
};self.timer.completion = ^{
    NSLog(@"complete done!");
};
复制代码

Swift版本

  最近喜欢上了OC,若有小伙伴须要Swift的版本的话能够留言或者私我,能够在写个Swift版本,😜。bash

结语

  使用简单,只须要把OMTimer.h和OMTimer.m拖入你的工程便可,知足大数的场景,可倒计时亦可增长计时,所有代码已在Github<github.com/oymuzi/OMKi…>上面,如对你有帮助,但愿获得你的一颗小星星✨,谢谢。/  若有疑问,直接留言或者发送邮件给我 admin@mypup.cn闭包

相关文章
相关标签/搜索