【发布时间】:2015-03-12 23:19:20
【问题描述】:
任何人都有诊断这些崩溃的经验吗?我有一个用户始终如一地获取它们,尽管我找到了与 iOS 相关的帖子,但我的应用程序并没有因相同类型的操作而崩溃...
【问题讨论】:
-
我发现如果您多次尝试执行同步 dispatch_queue,就会发生这种情况。 (同步dispatch_queue被多个线程调用,同时仍在工作。当队列执行块时,所有线程都在等待块完成。)
任何人都有诊断这些崩溃的经验吗?我有一个用户始终如一地获取它们,尽管我找到了与 iOS 相关的帖子,但我的应用程序并没有因相同类型的操作而崩溃...
【问题讨论】:
原因:
在 iOS / tvOS 中有队列 / 线程,每个线程都有自己的类型或优先级,也称为“服务质量”或简称“QOS”,表示 CPU 应处理此线程的紧急程度,可能性有:
一旦你在同一个队列中同时运行了太多任务,操作系统就会通知你它不能以相同的优先级同时执行所有这些任务(堆栈的大小有一个限制每个队列),其中显示“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")
【讨论】:
在 Swift 3 中重写 Shaybc 的答案:
DispatchQueue.global(qos: .background).async {
// some task to perform
print("This is my task")
})
【讨论】:
对于 Swift 3 使用:
DispatchQueue.global(qos: DispatchQoS.QoSClass.background).async {
// ...
}
【讨论】: