前言
好久没更新文章了,在掘金第一次发文章,还是给自己立一个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。
相关文章
猜你喜欢
- ASP.NET本地开发时常见的配置错误及解决方法? 2025-06-10
- ASP.NET自助建站系统的数据库备份与恢复操作指南 2025-06-10
- 个人网站服务器域名解析设置指南:从购买到绑定全流程 2025-06-10
- 个人网站搭建:如何挑选具有弹性扩展能力的服务器? 2025-06-10
- 个人服务器网站搭建:如何选择适合自己的建站程序或框架? 2025-06-10
TA的动态
- 2025-07-10 怎样使用阿里云的安全工具进行服务器漏洞扫描和修复?
- 2025-07-10 怎样使用命令行工具优化Linux云服务器的Ping性能?
- 2025-07-10 怎样使用Xshell连接华为云服务器,实现高效远程管理?
- 2025-07-10 怎样利用云服务器D盘搭建稳定、高效的网站托管环境?
- 2025-07-10 怎样使用阿里云的安全组功能来增强服务器防火墙的安全性?
快网idc优惠网
QQ交流群
您的支持,是我们最大的动力!
热门文章
-
2025-05-25 29
-
2025-05-29 64
-
2025-06-04 75
-
2025-05-25 93
-
2025-05-29 38
热门评论

