我正在使用AVFoundation
的{{1}}在游戏中播放MIDI音乐,我会定期调用MusicPlayer
来设置速度。我最近把游戏从Objective-C移植到了Swift,从那时起,我在几十次调用这个函数后就一直挂起/冻结。当冻结发生并且我暂停执行时,我的主线程始终处于以下状态:
MusicPlayerSetPlayRateScalar
发生这种情况时CPU使用率会跃升至100%,并且内存使用量开始稳步增长。我自己没有任何其他线程在运行。其他线程活动各不相同,但这是一个示例(其他线程的堆栈跟踪的顶级):
* 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和内存使用模式似乎表明不是这样。我该如何进一步调试?
(顺便说一句,在这种情况下,当我
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'
时,调试器有时会崩溃,但我怀疑这是否相关。)
答案 0 :(得分:1)
Apple人员在WWDC 2015 Core Audio视频中所说的一些东西让我觉得在这样的领域有很多C ++ voodoo在幕后进行,因此除非你确定,否则Swift无法与它接口注意事项(我不明白它们是什么)。在这种情况下,如果您不需要太远的向后兼容性,则可能需要尝试使用新的AVAudioSequencer。我发现它非常简单可靠。