5

我在我的应用程序中使用 CADisplayLink 作为计时器。我正在使用 CADisplayLink,因为我的应用非常依赖 CADisplayLink 的准确性/精度。就我而言,NSTimer 不是合适的替代品。

问题是偶尔,我需要 CADisplayLink 触发并调用它的选择器,而应用程序在后台。这甚至可能吗?我了解 CADisplayLink 与应用程序 UI 的刷新率相关联。这是否意味着,当我的应用程序在后台时,没有 UI,因此在这种情况下不可能使用 CADisplayLink?或者,是否可以通过更改我添加到的运行循环或更改forMode参数来以某种方式使用 CADisplayLink?或者也许使用一些 GCD 技巧/解决方法?

注意:我的应用正在使用 AudioPlayer,因此我启用了后台功能。我可以在后台运行其他代码。只是为了测试,我用 NSTimer 切换了我的 CADisplayLink,然后 NSTimer 触发并按照我的意愿调用它的选择器。我只是无法启动 CADisplayLink,也找不到任何关于在后台使用它的可能性的权威文档

这是与我的显示链接有关的当前代码:

func beginTimer(){

  dispatch_async(dispatch_get_main_queue()){
      self.displayLink = CADisplayLink(target: self, selector: "update")
      self.displayLink.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
  }
}

func update(){
  delegate?.executeCallback
 }
4

1 回答 1

2

没有在后台调用您的显示链接回调是一种无证的感觉,因为您无论如何都不应该绘制(实际上,如果您在后台执行任何 GPU 工作,您的应用程序就会被杀死)。

因此,如果您已经在使用音频和后台模式,为什么不尝试通过使用 remoteIO 音频单元* 进行音频并计算输出样本而不是屏幕刷新来实现您的计时呢?

使用此路径,您可以选择等于或小于通常的 60Hz 屏幕刷新的输出缓冲区大小。

我认为您应该能够获得可比较(并且可能更好)的计时精度,尽管在低功耗模式/其他应用程序交互中会有一些警告,iOS 可能会选择从您下方更改您的缓冲区大小。一些实验将是必要的。

*我认为AVAudioEngine还没有与此程序输出等效的东西。

于 2016-03-14T02:40:12.020 回答