我怎样才能定期使用GCD在后台运行代码块?

我怎样才能定期使用GCD在后台运行代码块? 我正在尝试编写一个带有几个子系统的游戏引擎,比如渲染,物理,游戏逻辑等等。 一些任务应该是事件驱动的,但是一些(如物理系统)应该在背景中定期调用(例如在1/100秒之后)。 我创build了一个代码块,但是如何在后台定期运行这个块呢? GCD是正确的工具吗?

你想要的是一个GCD调度源。 有关示例代码,请参阅创build计时器示例 。

正如@matt在注释中的注释,你可以使用计时器调度来源。 看到他的答案在那里正确的做法。

为了后代,这里是我的原始答案和一些替代scheme:

  1. 在你的渲染callback(比如使用CADisplayLink )中,启动计算这个(或下一个?)框架的物理的GCD作业。 如果您需要为每个渲染框架执行多个更新,只需要将该作业循环几次即可。

  2. 有一个物理线程自己睡觉,直到下一个需要做一些计算。 如果你有一个单独的线程,NSTimer可能有足够的分辨率以100赫兹唤醒你的线程。 (在主线程中,这是行不通的,因为runloop上的其他input源将阻止它始终快速地触发)如果NSTimer不起作用,只需计算剩下多less时间,直到下一次物理更新睡你的线程(通过,例如, [NSThread sleepForTimeInterval:]

  3. 有一个使用dispatch_after的块。

像这样的东西:

 dispatch_time_t next = dispatch_time(DISPATCH_TIME_NOW, 0); block = ^{ next = dispatch_time(next, 10000000L); // increment by 10 ms // do physics here dispatch_after(next, queue, block); } 

您可能需要在丢帧的时候更加智能一些(比如,在调用dispatch_after之前检测下一次是否已经过去等)

在Swift中,您可以使用GCD创build计时器:

 func CreateTimerDispatchSource(interval: UInt64, leeway: UInt64, queue: dispatch_queue_t, block: dispatch_block_t) -> dispatch_source_t { let timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue) dispatch_source_set_timer(timer, dispatch_walltime(nil, 0), interval, leeway) dispatch_source_set_event_handler(timer, block) return timer; } var timer = CreateTimerDispatchSource(5*NSEC_PER_SEC, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { // do some serious stuff } 

启动或恢复计时器:

 dispatch_resume(timer) 

暂停计时器:

 dispatch_suspend(timer)