可以从非主线程可靠地调用UIApplication.shared.applicationState吗?

时间:2017-09-21 00:06:45

标签: ios swift

我有一段代码在预定的计时器(大约每7秒钟)中运行,从网络下载图像,裁剪它,并在UIImageView中显示它。

我使用GPUImage2来帮助解决这个问题,但这显然(显然)它使用GPU来实现这一点。

问题是,当应用程序在后台运行时,我在执行基于gpu的裁剪时会出现随机崩溃。

我已经实现了一堆代码来在应用程序前往后台时停止计时器以防止出现这种情况。然而,有一种情况是应用程序在网络请求发生时进入后台,因此我需要在执行图像裁剪之前检查应用程序是否在后台(或更正式,不在前台) 。

我正在使用此代码(可能位于非主线程中):

guard (UIApplication.shared.applicationState == UIApplicationState.active) else {
    return
}
// perform GPU operation here.

但是,我仍然收到随机崩溃报告。可能在guard语句发生时和GPU操作发生时之间存在竞争,但这似乎不太可能,我从此部分收到了大量崩溃报告代码

我想知道是否存在线程问题,其中UIApplication.shared.applicationState应该只在主线程上读取,并且因为我不在主线程上,所以值是不正确(说应用程序处于活动状态时,实际上它不是),但是文档不会给出任何指示。

您怎么看?

2 个答案:

答案 0 :(得分:1)

最好的选择是防御性编码。大多数UIKit方法都不是线程安全的,因此可以安全地假设UIApplication.shared.applicationState只能在主线程中工作。

一个简单的解决方案是确保您在主线程上,例如:

DispatchQueue.main.async {
    guard UIApplication.shared.applicationState == .active else {
        return
    }
    // perform GPU operation here, possibly within another DispatchQueue to execute in the background
}

答案 1 :(得分:0)

enter image description here你可能是对的。尝试在Xcode 9中运行,它可能会将此标记为非法操作 - 调用主线程 - 并发出运行时警告。