任何Core MIDI通话都会导致应用无响应

时间:2019-05-08 11:08:13

标签: ios coremidi

我在使用的两个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服务器设置为这种无响应状态:

  1. 在Mac上的“音频/ MIDI设置”中设置网络MIDI会话。
  2. 在iOS应用中,连接到该网络MIDI会话。
  3. 让Mac自然进入睡眠状态(从Apple菜单调用睡眠似乎不会触发问题)。
  4. 一旦Mac进入睡眠状态,请在iOS应用中执行一些称为Core MIDI的操作。

因此,就像iOS Core MIDI服务器已断开与Mac的MIDI网络的连接,而是继续尝试执行。


更新时间:2019-05-17

Apple回应了我的错误报告(#50657978),说它与另一个报告(#49583498)相同,将被关闭。至少他们知道该错误。

1 个答案:

答案 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的调用都可能导致警报不显示(例如主队列将被阻止。)