2015-10-03 115 views
1

我使用AVFoundationMusicPlayer在游戏中播放MIDI音乐,我定期拨打MusicPlayerSetPlayRateScalar设置节奏。我最近将游戏从Objective-C移植到了Swift中,从那以后,我几次打电话给这个函数后,我一直在挂起/冻结。当冻结发生,我暂停执行,我的主线程总是坐在下面的状态:MusicPlayerSetPlayRateScalar在__psynch_mutexwait中导致挂起/冻结

* thread #1: libsystem_kernel.dylib`__psynch_mutexwait + 8, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP * frame #0: libsystem_kernel.dylib`__psynch_mutexwait + 8 frame #1: libsystem_pthread.dylib`_pthread_mutex_lock_wait + 96 frame #2: AudioToolbox`CAMutex::Lock() + 52 frame #3: AudioToolbox`SequencePlayer::SetTempoScaleFactor(double) + 36 frame #4: AudioToolbox`MusicPlayerSetPlayRateScalar + 136

CPU使用率跳转到100%的时候出现这种情况,和内存的使用率开始稳步增长。我没有任何其他线程可以运行。其他线程活动变化,但这里有一个例子(其他线程的堆栈跟踪的最高级别):

thread #5: libsystem_kernel.dylib`kevent_qos + 8, queue = 'com.apple.libdispatch-manager' thread #6: libsystem_kernel.dylib`__semwait_signal + 8, name = 'gputools.smt_poll.0x126fe8680' thread #10: libsystem_kernel.dylib`mach_msg_trap + 8, name = 'com.apple.coreaudio.AQClient' thread #11: libsystem_kernel.dylib`semaphore_wait_trap + 8, name = 'AudioStreamerImpl::sIOWorkerProcess' thread #12: libc++abi.dylib`__cxa_decrement_exception_refcount + 32, name = 'AURemoteIO::IOThread' thread #13: libsystem_kernel.dylib`mach_msg_trap + 8, name = 'AURemoteIO::IOThread'

我已经猜到了某种僵局给出的互斥体和信号量,但CPU和内存使用模式似乎表明否则。我怎样才能进一步调试呢?

(顺便说一句,调试器有时会崩溃,当我在这种情况下做bt all,但我怀疑的关联。)

+0

我打算猜测在背景上会出现某种C++ voodoo,这使得Swift无法做到这一点。有没有可能使用新的AVAudioSequencer代替? – matt

+0

@matt Woah,我还没有听说过'AVAudioSequencer'(不出意外,因为目前还没有API文档)。我刚刚使用它重写了我的音乐播放器(约有1/4的代码),并且冻结消失了。真棒! – phu

+0

很高兴来到这里!我已经给出了我的评论作为答案,所以我们可以关闭这一个。很高兴,这工作。 – matt

回答

1

的东西,苹果的乡亲在WWDC说2015核心音频视频让我觉得有很多的C++ voodoo会在幕后这样的领域中出现,因此除非你采取了一定的预防措施(我不明白它们是什么),否则Swift无法与之交互。在这种情况下,如果你不需要向后兼容太多,你可能想尝试使用新的AVAudioSequencer。我发现它非常简单可靠。