【问题标题】:iOS - How to understand and properly debug this type of crash : com.apple.root.background-qos?iOS - 如何理解和正确调试这种类型的崩溃:com.apple.root.background-qos?
【发布时间】:2019-09-05 11:55:09
【问题描述】:

我知道这个问题已经被问过好几次了,但要么没有回答,要么答案完全没有帮助。

这是我的崩溃报告:

This question 尤其是 cmets 帮助我理解(某种)我的问题。

从您的崩溃日志 com.apple.root.background-qos 看来,这是线程请求,由于它存在,因为它无法再接受任何请求,因此可能会过度提交。

如果我理解正确,线程处理请求可能无法处理更多请求?

如何调试和测试这个?我无法重现崩溃。

注意:在我的启动器服务中,我正在执行 5 或 6 个请求,每个请求在完成后以 dispatchGroup.enter / .leave 分隔,如下所示:

dispatchGroup.enter()
self.fetchObservationForecast(lat: lat, lon: lon) { result in
     switch result {
     case .success(let observationForecast) :
          print("Observation Forecast request succeeded")
          model["observationForecast"] = observationForecast
          break
     case .failure(let error) :
          print("Observation Forecast request failed : \(error)")
          model["observationForecast"] = error
          break
     }
     dispatchGroup.leave()
}

我看错地方了吗?我如何测试和重现它以提交修复?

任何帮助将不胜感激。

【问题讨论】:

  • 崩溃是由所指示的 LauncherService 方法中的闭包引起的。跟踪中的第一行表明您在设置 Dictionary 值时崩溃了。可变的 Swift 字典不是线程安全的,而且它与 background.qos 指针一起让我觉得你在多个线程上读/写字典。这可能类似于上面的 model["observationForecast"] = 代码。
  • 感谢您的分析。这对我有很大帮助。如果你想要接受的答案,你可以写一个答案,因为我认为你是对的。
  • 谢谢,祝你好运。

标签: ios swift crash qos


【解决方案1】:

崩溃是由所指示的 LauncherService 方法中的闭包引起的。跟踪表明您在设置 Dictionary 值时崩溃了。

可变 Swift 字典不是线程安全的,这一事实以及 background.qos 指示符让我觉得您是在多个线程上读/写字典。

这可能类似于下面的 model["observationForecast"] = 代码。

dispatchGroup.enter()
self.fetchObservationForecast(lat: lat, lon: lon) { result in
     switch result {
     case .success(let observationForecast) :
          print("Observation Forecast request succeeded")
          model["observationForecast"] = observationForecast
          break
     case .failure(let error) :
          print("Observation Forecast request failed : \(error)")
          model["observationForecast"] = error
          break
     }
     dispatchGroup.leave()
}

【讨论】:

  • 这个非线程安全的可变字典的替代品是什么?
  • 一种方法可能是将模型的所有字典访问异步分派到主线程。
  • 好吧,你的解决方案和这个medium.com/@mohit.bhalla/…有什么区别?
  • 这就是我要说的。该示例不需要主线程并被包装到一个可重用的类中,但它仍然在一个线程上完成所有工作。您的字典访问没有理由需要在主线程上运行,因此使用不同的队列可以说是更好的解决方案。重要的是所有访问都发生在同一个线程上,不管它是什么。
猜你喜欢
  • 2023-03-17
  • 1970-01-01
  • 2011-01-04
  • 1970-01-01
  • 2020-02-15
  • 1970-01-01
  • 2012-07-12
  • 2012-10-30
  • 2018-04-15
相关资源
最近更新 更多