创建DISPATCH_SOURCE_TYPE_TIMER派发源

本文介绍如何使用定时器dispatchsource发起周期性任务,包括配置定时精度、触发时机及使用不同函数实现不同需求的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定时器dispatch source定时产生事件,可以用来发起定时执行的任务,如游戏或其它图形应用,可以使用定时器来更新屏幕或动画。你也可以设置定时器,并在固定间隔事件中检查服务器的新信息。
所有定时器dispatch source都是间隔定时器,一旦创建,会按你指定的间隔定期递送事件。你需要为定时器dispatch source指定一个期望的定时器事件精度,也就是leeway值,让系统能够灵活地管理电源并唤醒内核。例如系统可以使用leeway值来提前或延迟触发定时器,使其更好地与其它系统事件结合。创建自己的定时器时,你应该尽量指定一个leeway值。
就算你指定leeway值为0,也不要期望定时器能够按照精确的纳秒来触发事件。系统会尽可能地满足你的需求,但是无法保证完全精确的触发时间。
当计算机睡眠时,定时器dispatch source会被挂起,稍后系统唤醒时,定时器dispatch source也会自动唤醒。根据你提供的配置,暂停定时器可能会影响定时器下一次的触发。如果定时器dispatch source使用 dispatch_time 函数或 DISPATCH_TIME_NOW 常量设置,定时器dispatch source会使用系统默认时钟来确定何时触发,但是默认时钟在计算机睡眠时不会继续。
如果你使用 dispatch_walltime 函数来设置定时器dispatch source,则定时器会根据挂钟时间来跟踪,这种定时器比较适合触发间隔相对比较大的场合,可以防止定时器触发间隔出现太大的误差。
下面是定时器dispatch source的一个例子,每30秒触发一次,leeway值为1,因为间隔相对较大,使用 dispatch_walltime 来创建定时器。定时器会立即触发第一次,随后每30秒触发一次。 MyPeriodicTask 和 MyStoreTimer 是自定义函数,用于实现定时器的行为,并存储定时器到应用的数据结构。
虽然定时器dispatch source是接收时间事件的主要方法,你还可以使用其它选择。如果想在指定时间间隔后执行一个block,可以使用  dispatch_after 或 dispatch_after_f  函数。这两个函数非常类似于dispatch_async,但是只允许你指定一个时间值,时间一到就自动提交block到queue中执行,时间值可以指定为相对或绝对时间。
dispatch_source_t createTimerDispatchSource(uint64 interval,
                                            uint64 leeway,
                                            dispatch_queue_t queue,
                                            dispatch_block_t block)
{
    //1:创建派发源
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    if(timer){
        //2:配置定时器派发源,第二参数设置第一次触发时间,你可以使用dispatch_walltime函数,也可以使用dispatch_time或DISPATCH_TIME_NOW
        dispatch_source_set_timer(timer, dispatch_walltime(NULL, interval), interval, leeway);
        //3:设置事件响应体
        dispatch_source_set_event_handler(timer, block);
        //4:启动派发源
        dispatch_resume(timer);
    }
    return timer;
}
int main(int argc, const char * argv[]) {
    
    @autoreleasepool {
        
        NSLog(@"==========定时器派发源===========");
        __block int count = 0;
        dispatch_source_t timer = createTimerDispatchSource(3ull * NSEC_PER_SEC,//事件间隔时间
                                                            0ull * NSEC_PER_SEC,//偏差,0偏差最好(虽然达不到)
                                                            dispatch_get_main_queue(),
                                                            ^{
                                                                NSLog(@"on timer");
                                                                count++;
                                                            });
        
        while (YES) {
            if (count == 3) {
                dispatch_source_cancel(timer);
                break;
            }
            
            [[NSRunLoop currentRunLoop]runMode:NSDefaultRunLoopMode beforeDate:[NSDate date]];
        }
        
    }
    
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值