首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >任何核心MIDI调用都会导致应用程序失去响应

任何核心MIDI调用都会导致应用程序失去响应
EN

Stack Overflow用户
提问于 2019-05-08 11:08:12
回答 1查看 357关注 0票数 4

我在几个iOS应用程序中遇到了Core的问题,我从apps下载了另一个应用程序。

似乎正在发生的是Core服务器崩溃。在此之后,与Core函数或属性的任何交互都会使调用应用程序失去响应。下面的行在AppDelegate的didFinishLaunchingWithOptions:

代码语言:javascript
复制
[MIDINetworkSession defaultSession].enabled = YES;

执行在此时停止,在调试时导致永久挂起,否则会导致#8badf00d崩溃。

即使Core函数应该返回一个OSStatus (返回值永远不会返回),也会发生这种情况:

代码语言:javascript
复制
OSStatus s = MIDIObjectGetStringProperty(ref, kMIDIPropertyDisplayName, (CFStringRef*)&string);

此调用(位于PGMidi库中)也将挂起,不返回s。解决问题的唯一方法是重新启动设备。

核心MIDI服务器变得没有响应似乎与从连接的Mac上运行多个网络会话有关,但我还没有找到可靠复制的方法。除了我自己的应用程序(使用MIKMIDI库)之外,我还经历了从apps下载的midimittr的反应迟钝的行为。

当然,我无法控制核心MIDI服务器是否会变得没有响应能力。但是,在打电话之前是否有办法检查MIDI服务器的状态,这可能会使我的应用程序失去响应?

更新:2019年-05-10

我发现可以通过以下步骤使iOS核心MIDI服务器处于这种无响应状态:

  1. 在音频/ MIDI设置中在Mac上设置网络MIDI会话。
  2. 在iOS应用程序中,连接到Network会话。
  3. 让Mac自然入睡(从Apple菜单调用睡眠似乎不会触发问题)。
  4. 一旦Mac进入睡眠状态,在iOS应用程序中做一些叫做Core的事情。

因此,就像iOS核心MIDI服务器已经失去了与MIDI网络的连接,但仍在继续尝试和执行。

更新:2019年-05-17

苹果回应了我的错误报告(#50657978),称这是另一份报告(#49583498)的复制,将被关闭。至少他们意识到了这个错误。

更新: 2019-07-17

通过音频音乐设置连接Core网络,还可以更快地进入Core挂起状态(用于调试),然后在iOS设备上备份应用程序并切换飞机模式。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-28 10:47:34

有关最新更新和最终解决方案,请参阅下面

我设法想出了这个问题的部分解决办法。(唉,由于根本原因似乎嵌入了苹果的代码,一个完整的解决方案是不可能的。)

在我的AppDelegate中,我现在运行一个例程,它可以检测对Core的调用是否会超时:

代码语言:javascript
复制
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. Note: app will crash anyway at some point in the future.
        
    case .success:
        break    // All good, continue as before
    }
}

这里要注意的一点是:如果您打算在midiNetworkTimeoutResult == .timeOut的情况下显示一个警报,那么请记住,在此之后发生的对Core的任何调用都可能导致警报不出现(因为主队列将被阻塞)。

更新: 2019-07-17

上面提到的解决方案是很重要的,如果您在上面的.timedOut案例中结束,这个应用程序在将来的某个时候会崩溃,因为它会赶上MIDINetworkSession.default().isEnabled调用。

坠机前的间隙约为5分钟,因此有足够的时间显示警报并建议用户重新启动设备。

更新: 2019-08-14

推荐解决方案

苹果在iOS 12.4中似乎已经解决了这个问题。然后,解决方案是建议用户更新到iOS 12.4或更高版本。

(而且,这个问题似乎只影响到iOS 12.2和12.3版本。)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56039369

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档