所以我在我的Cocoa应用程序中重构了一个核心部分(我真的不得不这样做了!)然后我就遇到了问题。
快速概述:我的应用程序控制QuickTime电影的播放,以便它们与外部时间码同步。
因此,外部时间码到达CoreMIDI回调线程并每秒发送到应用程序大约25次。然后检查并调整同步,如果需要的话。 所有这些检查和调整都在主线程上完成。
即使我将所有处理都放在后台线程上,因为我目前正在使用大量的GCD块,所以我需要重写很多函数,以便可以从NSThread调用它们。 。所以我想首先确定它是否能解决我的问题。
问题
我的核心MIDI回调总是及时调用,但调度到主队列的GCD块有时会被阻止长达500毫秒。可以理解的是,如果发生这种情况,调整同步并不是很有效。我找不到它的原因,所以我猜我正在做一些阻止主线程的事情。
我熟悉乐器,但是我找不到合适的模式来查看是什么让我的消息无法及时处理。
如果有人能提供帮助,我将不胜感激。 不知道我能做些什么。 提前谢谢!
答案 0 :(得分:2)
您可能正在阻止主线程,或者您可能会使用事件充斥它。
我建议三件事:
获取时间码到达CoreMIDI回调线程的时间戳(请参阅mach_absolute_time()
。然后获取主线程工作完成时的当前时间。然后您可以根据多少进行相应调整在发布到主线程和实际处理之间已经过了一段时间。
创建某种合并机制,以便在主线程被阻止时,临时时间码事件(现在已过期)被抛出。这可以像全局NSUInteger一样简单,每次收到事件时都会递增。分派到主队列的块可以在创建时捕获当前值,然后在处理时检查它。如果它的差异超过N(你需要确定N),那么抛出事件就会有更多的事情发生。
考虑不为每个时间码通知向主线程发送事件。每秒25次调整大量工作。如果每秒仅处理5次就会产生足够好的"感性体验,那就是节省了大量的工作。
通常,检测主事件循环有点棘手。仪器中的CPU分析器非常有用。这可能会让人感到惊讶,但Allocations工具也是如此。特别是,您可以使用Allocations工具来测量内存吞吐量。如果存在大量的瞬态(短期)分配,它会在执行所有这些分配/解除分配时耗费大量的CPU时间。