我在使用的两个iOS应用程序以及从App Store下载的另一个应用程序中遇到了Core MIDI的问题。
出现的 是Core MIDI服务器崩溃。在发生这种情况之后,与Core MIDI功能或属性的任何交互都会使调用的应用程序无响应。以下行在AppDelegate的didFinishLaunchingWithOptions:
中:
[MIDINetworkSession defaultSession].enabled = YES;
执行会在此时停止,从而导致调试时永久挂起,否则将导致#8badf00d
崩溃。
即使Core MIDI函数应该返回OSStatus,也不会发生这种情况-返回值永远不会回来:
OSStatus s = MIDIObjectGetStringProperty(ref, kMIDIPropertyDisplayName, (CFStringRef*)&string);
此调用(在PGMidi库中)也被挂起,未返回s
。解决此问题的唯一方法是重新启动设备。
Core MIDI服务器无响应似乎与从连接的Mac上运行多个网络会话有关,但我无法确定可靠复制的方法。除了我自己的应用程序(使用MIKMIDI库)以外,我还从midimittr体验到无响应的行为,该行为是从App Store下载的。
当然,我无法控制Core MIDI Server是否无响应。但是,有没有办法在发出可能使我的应用无响应的呼叫之前 检查MIDI服务器的状态?
更新时间:2019-05-10
我发现可以按照以下步骤将iOS Core MIDI服务器设置为这种无响应状态:
因此,就像iOS Core MIDI服务器已断开与Mac的MIDI网络的连接,而是继续尝试执行。
更新时间:2019-05-17
Apple回应了我的错误报告(#50657978),说它与另一个报告(#49583498)相同,将被关闭。至少他们知道该错误。
答案 0 :(得分:0)
我已经设法解决了这个问题。 (A,因为根本原因似乎已嵌入到Apple的代码中,所以不可能提供完整的解决方案。)
现在我在AppDelegate中运行一个例程,该例程可以检测对Core MIDI的调用是否会超时:
func enableMIDINetworkSession() {
let midiNetworkGroup = DispatchGroup()
midiNetworkGroup.enter()
DispatchQueue.global(qos: .background).async {
MIDINetworkSession.default().isEnabled = true
midiNetworkGroup.leave()
}
// If `midiNetworkGroup.leave()` is not reached in the closure above, then the result below will be `.timeOut`
let midiNetworkTimeoutResult = midiNetworkGroup.wait(timeout: DispatchTime.now() + 10.0)
switch midiNetworkTimeoutResult {
case .timedOut:
{ ... } // Calls to Core MIDI will cause app to hang. Handle as required
case .success:
break // All good, continue as before
}
}
此处需要注意的事情:如果您打算在midiNetworkTimeoutResult == .timeOut
的情况下显示警报,请记住,此后立即发生的任何对Core MIDI的调用都可能导致警报不显示(例如主队列将被阻止。)