先了解一些基本知识
第一:
Dispatch Source
的几种种类:
1
、
DISPATCH_SOURCE_TYPE_DATA_ADD
变量增加
2
、
DISPATCH_SOURCE_TYPE_DATA_OR
变量
OR
3
、
DISPATCH_SOURCE_TYPE_MACH_SEND MACH
端口发送
4
、
DISPATCH_SOURCE_TYPE_MACH_RECV MACH
端口接收
5
、
DISPATCH_SOURCE_TYPE_MEMORYPRESSURE
内存压力
(
注:
iOS8
后可用
)
6
、
DISPATCH_SOURCE_TYPE_PROC
检测到与进程相关的事件
7
、
DISPATCH_SOURCE_TYPE_READ
可读取文件映像
8
、
DISPATCH_SOURCE_TYPE_SIGNAL
接收信号
9
、
DISPATCH_SOURCE_TYPE_TIMER
定时器
10
、
DISPATCH_SOURCE_TYPE_VNODE
文件系统有变更
11
、
DISPATCH_SOURCE_TYPE_WRITE
可写入文件映像
第二:
dispatch_source_t
dispatch_source_create(dispatch_source_type_t type,
uintptr_t handle,
unsigned long mask,
dispatch_queue_t _Nullable queue);
第一个参数:
dispatch_source_type_t type
为设置
GCD
源方法的类型,前面已经列举过了。
第二个参数:
uintptr_t handle
,暂时没有使用,传
0
即可。
第三个参数:
unsigned long mask
,使用
DISPATCH_TIMER_STRICT
,会引起电量消耗加剧,毕竟要求精确时间,所以一般传
0
即可,视业务情况而定。
第四个参数:
dispatch_queue_t _Nullable queue
队列,将定时器事件处理的
Block
提交到哪个队列之上。可以传
Null
,默认为全局队列。
第三:
dispatch_source_set_timer(dispatch_source_t source,
dispatch_time_t start,
uint64_t interval,
uint64_t leeway);
第一个参数:
dispatch_source_t source
,创建好的
dispatch_source_t
。
第二个参数:
dispatch_time_t start,
定时器开始时间,类型为
dispatch_time_t
,其
API
的
abstract
标明可参照
dispatch_time()
和
dispatch_walltime()
,同为设置时间,但是后者为
“
钟表
”
时间,相对比较准确,所以选择使用后者。
dispatch_walltime(const struct timespec *_Nullable when, int64_t delta),
参数
when
可以为
Null
,默认为获取当前时间,参数
delta
为增量,即获取当前时间的基础上,增加
X
秒的时间为开始计时时间,此处传
0
即可。
第三个参数:
uint64_t interval
,定时器间隔时长,由业务需求而定。
第四个参数:
uint64_t leeway
,
允许误差,此处传
0
即可。
第四:
dispatch_source_set_event_handler(dispatch_source_t source,
dispatch_block_t _Nullable handler);
第一个参数:
dispatch_source_t source
,创建好的
dispatch_source_t
。
第二个参数:
dispatch_block_t _Nullable handler
,定时器执行的动作,需要处理的业务逻辑
Block
。
第五:
dispatch_resume(dispatch_object_t object);
定时器创建完成并不会运行,需要主动去触发。
第六:
dispatch_source_cancel(dispatch_source_t source);
定时器运行完了可以终止,即关闭
方法:
__block
int
timeout = 60;
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);
dispatch_source_set_timer
(timer,
dispatch_walltime
(
NULL
, 0),1.0*
NSEC_PER_SEC
, 0);
//
每秒执行
dispatch_source_set_event_handler
(timer, ^{
if
(timeout<=0){
//
倒计时结束,关闭
dispatch_source_cancel
(timer);
dispatch_async
(
dispatch_get_main_queue
(), ^{
//
设置界面的按钮显示
根据自己需求设置
});
}
else
{
NSString
*strTime = [
NSString
stringWithFormat
:
@"%.2d
秒后重新获取验证码
"
, timeout];
dispatch_async
(
dispatch_get_main_queue
(), ^{
NSLog
(
@"%@"
,strTime);
//
设置界面的按钮显示
根据自己需求设置
});
timeout--;
}
});
//
启动
timer
dispatch_resume
(timer);