0

所以我在我的 Cocoa 应用程序中重组了一个核心部分(我真的必须这样做!),从那时起我就遇到了问题。

快速概述:我的应用程序控制 QuickTime 电影的播放,以便它们与外部时间码同步。

因此,外部时间码到达 CoreMIDI 回调线程并每秒大约 25 次发布到应用程序。然后检查同步并在需要时进行调整。所有这些检查和调整都是在主线程上完成的。

即使我将所有处理都放在后台线程上,这也是一项繁重的工作,因为我目前正在使用很多 GCD 块,并且我需要重写很多函数以便可以从 NSThread 调用它们。所以我想先确定它是否能解决我的问题。

问题

我的核心 MIDI 回调总是被及时调用,但被分派到主队列的 GCD 块有时会被阻塞长达 500 毫秒。可以理解的是,如果发生这种情况,调整同步将无法正常工作。我找不到原因,所以我猜我正在做一些阻塞主线程的事情。

我对 Instruments 很熟悉,但我找不到合适的模式来查看是什么让我的消息无法及时处理。

如果有人可以提供帮助,我将不胜感激。不知道我能做些什么。提前致谢!

4

2 回答 2

4

看门狗

您可以使用当主线程停止时间时停止的看门狗

https://github.com/wojteklu/Watchdog

你可以使用 cocoapod 安装它

pod 'Watchdog'
于 2016-12-04T15:45:56.223 回答
2

您可能阻塞了主线程,或者您可能正在用事件淹没它。

我建议三件事:

  • 获取时间码到达 CoreMIDI 回调线程的时间戳(请参阅mach_absolute_time()。然后获取主线程工作完成时的当前时间。然后您可以根据发布到主线程和实际上正在处理。

  • 创建某种合并机制,以便当您的主线程被阻塞时,临时时间码事件(现在已过时)被丢弃。这可以像每次接收到事件时递增的全局 NSUInteger 一样简单。分派到主队列的块可以在创建时捕获当前值,然后在处理时检查它。如果它的差异超过 N(N 供您确定),则放弃该事件,因为还有更多的事件在进行中。

  • 考虑不要为每个时间码通知向主线程发送事件。每秒 25 次调整是很多工作。如果每秒仅处理 5 次就可以产生“足够好”的感知体验,那么这将节省大量工作。

一般来说,检测主事件循环有点棘手。Instruments 中的 CPU 分析器非常有用。这可能会让人感到意外,但分配工具也可以。特别是,您可以使用分配工具来测量内存吞吐量。如果有大量的临时(短期)分配,它会消耗大量的 CPU 时间来完成所有这些分配/解除分配。

于 2013-09-04T16:06:40.407 回答