1、简述
dispatch_source是基础数据类型
,用于协调特定底层系统事件的处理。
- dispatch_source替代了异步回调函数,来处理系统相关的事件,当配置一个dispatch时,你需要指定
监测的事件
、dispatch queue
、以及处理事件的代码(block或函数)`。当事件发生时,dispatch source会提交你的block或函数到指定的queue去执行 - 使用 Dispatch Source 而不使用 dispatch_async 的唯一原因就是利用
联结的优势
。 - 联结的大致流程为:在任一线程上调用它的一个函数dispatch_source_merge_data后,
会执行Dispatch Source事先定义好的句柄
(可以把句柄简单理解为一个block),这个过程叫 Custom event(用户事件)。是 dispatch source 支持处理的一种事件。- 简单来说:这种事件是由你调用 dispatch_source_merge_data 函数来向自己发出的信号。
- 特点
- 其CPU负荷非常小,金陵不占用资源
- 结的优势
2、使用
2.1 创建dispatch源
代码语言:javascript复制dispatch_source_t source = dispatch_source_create(dispatch_source_type_t type, uintptr_t handle, unsigned long mask, dispatch_queue_t queue)
2.1.1 参数说明
2.1.2 Dispatch Source 种类
image.png
2.1.3 注意
DISPATCH_SOURCE_TYPE_DATA_ADD
当同一时间,一个事件的的触发频率很高,那么Dispatch Source会将这些响应以ADD的方式进行累积,然后等系统空闲时最终处理,如果触发频率比较零散,那么Dispatch Source会将这些事件分别响应;DISPATCH_SOURCE_TYPE_DATA_OR
自定义的事件,但是它是以OR的方式进行累积;
2.2 常用函数
代码语言:javascript复制//挂起队列
dispatch_suspend(queue)
//分派源创建时默认处于暂停状态,在分派源分派处理程序之前必须先恢复
dispatch_resume(source)
//向分派源发送事件,需要注意的是,不可以传递0值(事件不会被触发),同样也不可以传递负数。
dispatch_source_merge_data
//设置响应分派源事件的block,在分派源指定的队列上运行
dispatch_source_set_event_handler
//得到分派源的数据
dispatch_source_get_data
//得到dispatch源创建,即调用dispatch_source_create的第二个参数
uintptr_t dispatch_source_get_handle(dispatch_source_t source);
//得到dispatch源创建,即调用dispatch_source_create的第三个参数
unsigned long dispatch_source_get_mask(dispatch_source_t source);
////取消dispatch源的事件处理--即不再调用block。如果调用dispatch_suspend只是暂停dispatch源。
void dispatch_source_cancel(dispatch_source_t source);
//检测是否dispatch源被取消,如果返回非0值则表明dispatch源已经被取消
long dispatch_source_testcancel(dispatch_source_t source);
//dispatch源取消时调用的block,一般用于关闭文件或socket等,释放相关资源
void dispatch_source_set_cancel_handler(dispatch_source_t source, dispatch_block_t cancel_handler);
//可用于设置dispatch源启动时调用block,调用完成后即释放这个block。也可在dispatch源运行当中随时调用这个函数。
void dispatch_source_set_registration_handler(dispatch_source_t source, dispatch_block_t registration_handler);
3、倒计时器
代码语言:javascript复制- (void)demo{
//倒计时时间
__block int timeout = 3;
//创建队列
dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
//创建timer
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, globalQueue);
//设置1s触发一次,0s的误差
/*
- source 分派源
- start 数控制计时器第一次触发的时刻。参数类型是 dispatch_time_t,这是一个opaque类型,我们不能直接操作它。我们得需要 dispatch_time 和 dispatch_walltime 函数来创建它们。另外,常量 DISPATCH_TIME_NOW 和 DISPATCH_TIME_FOREVER 通常很有用。
- interval 间隔时间
- leeway 计时器触发的精准程度
*/
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源
dispatch_source_cancel(timer);
}else{
timeout--;
dispatch_async(dispatch_get_main_queue(), ^{
//更新主界面的操作
NSLog(@"倒计时 - %d", timeout);
});
}
});
//开始执行dispatch源
dispatch_resume(timer);
}
转载自: Style_月月