【问题标题】:Consistent Dispatch queue: com.apple.root.default-qos.overcommit crash一致的调度队列:com.apple.root.default-qos.overcommit 崩溃
【发布时间】:2015-03-12 23:19:20
【问题描述】:

任何人都有诊断这些崩溃的经验吗?我有一个用户始终如一地获取它们,尽管我找到了与 iOS 相关的帖子,但我的应用程序并没有因相同类型的操作而崩溃...

【问题讨论】:

  • 我发现如果您多次尝试执行同步 dispatch_queue,就会发生这种情况。 (同步dispatch_queue被多个线程调用,同时仍在工作。当队列执行块时,所有线程都在等待块完成。)

标签: macos cocoa crash


【解决方案1】:

原因:

在 iOS / tvOS 中有队列 / 线程,每个线程都有自己的类型或优先级,也称为“服务质量”或简称“QOS”,表示 CPU 应处理此线程的紧急程度,可能性有:

  • QOS_CLASS_DEFAULT
  • QOS_CLASS_USER_INITIATED
  • QOS_CLASS_UTILITY
  • QOS_CLASS_BACKGROUND
  • QOS_CLASS_UNSPECIFIED
  • QOS_CLASS_USER_INTERACTIVE

一旦你在同一个队列中同时运行了太多任务,操作系统就会通知你它不能以相同的优先级同时执行所有这些任务(堆栈的大小有一个限制每个队列),其中显示“OverCommit”,这意味着您已过度提交队列(在您的情况下为“Default-QOS”队列)并且它退出,因为它此时无法接收更多任务并以时尚方式执行它们你想要的。

解决方案:

您应该首先找到导致此崩溃的“dispatch_async”命令,然后使用其他队列之一(这意味着该任务的响应速度比预期的慢),

通常开发人员不会考虑它,而只是使用默认优先级/队列的主队列,如下所示:

dispatch_async(dispatch_get_main_queue()) {
    // some task to perform
    print("This is my task")
}

为了解决这个问题(如果应用程序通知您您已过度使用主队列)是将其更改为其他队列之一,如下所示:

let qualityOfServiceClass = QOS_CLASS_BACKGROUND
let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
dispatch_async(backgroundQueue, {
    // some task to perform
    print("This is my task")
})

如果您不需要后台(或并行)执行,您甚至可以完全忽略 dispatch_async 命令并简单地执行如下命令:

// some task to perform
print("This is my task")

【讨论】:

  • "(如果应用通知你已经过度使用主队列)"你怎么知道的?
【解决方案2】:

在 Swift 3 中重写 Shaybc 的答案:

DispatchQueue.global(qos: .background).async {
  // some task to perform
  print("This is my task")
})

【讨论】:

    【解决方案3】:

    对于 Swift 3 使用:

    DispatchQueue.global(qos: DispatchQoS.QoSClass.background).async { 
        // ... 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-15
      • 2014-07-13
      • 2017-07-20
      • 2017-07-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多