iOS简单易用的GCD计时器的实现原理

2025-05-29 0 57

前言

好久没更新文章了,在掘金第一次发文章,还是给自己立一个flag每周至少更新一篇文章,可能文章的质量还不是很如意,希望通过写文章来提高自己文笔,以及记录自己学习中的遇到的问题解决方案。

在学习ios过程中,想定大家对于定时器都不陌生,在日常开发中总会碰到需要计时器的功能,常见的定时器有nstimer、gcd、cadisplaylink。网上也有很多的教程介绍三者的区别,今天主要讲的是gcd这种方式使用以及封装。

三者概括区别

优点 缺点
nstimer 使用简单 受runloop影响会导致计时不精准
cadisplaylink 精度高      cpu负载的时候会影响触发事件,且触发事件大于触发间隔会导致掉帧现象。
gcd 较精准 代码较多,基本不受其他影响

总结:nstimer和cadisplaylink易受影响,而gcd虽然代码多,但是可控性非常强。

gcd

?

1

2

3

4

5

6

7

8

9

10
/** 获取一个全局的线程来运行计时器*/

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....

});

开启、继续已暂停的定时器

?

1
dispatch_resume(timer);

暂停定时器

?

1

2

3

4

5
/** 挂起的时候注意,多次暂停的操作会导致线程锁的现象,即多少次暂停,

* 对应多少次的继续操作,即dispatch_suspend和dispatch_resume

* 是成对出现的,计时器才会继续工作。

*/

dispatch_suspend(timer);

结束定时器

?

1
dispatch_source_cancel(timer);

构思封装

写代码之前构思好功能模块以及会遇到的问题的解决方案、代码逻辑,再来下手写代码,会有事半功倍的效果。

  • 必然包含开始、暂停、继续、停止、重置功能
  • 时间计算过程中因浮点数计算会丢失精度,计算过程应采用nsdecimal
  • 时间转换考虑到精度以及便利性,采用系统的时间转换方法,时区置为gmt
  • 由于app进入后台,若未开启后台任务的开关,计时器将会停止,再次进入app又会继续,故采用监听app状态的方式记录app进入后台与前台的时间戳,并与截止时间相比,是否继续计时还是结束计时并回调。
  • 计时器返回的结果若采用字符串则还需处理,故使用了一个时间类来把结果返回,可以进行自定义操作
  • 倒计时的结果返回和结束通知采用闭包形式

部分代码

?

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
/** 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;

}

?

1
@property (nonatomic, strong) omtimer *timer;

?

1

2

3

4

5

6

7

8

9
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版本,:stuck_out_tongue_winking_eye:。

结语

使用简单,只需要把omtimer.h和omtimer.m拖入你的工程即可,满足大数的场景,可倒计时亦可增加计时,全部代码已在github<https://github.com/oymuzi/omkit/

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持快网idc。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 iOS简单易用的GCD计时器的实现原理 https://www.kuaiidc.com/89085.html

相关文章

发表评论
暂无评论